├── .devcontainer
└── devcontainer.json
├── .github
├── CODE_OF_CONDUCT.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── images
├── api-center.png
├── gbb.png
├── import-bian.png
├── import-from-aws.png
├── import-from-azure-apim.png
├── import-from-gcp.png
├── import-from-generic-openapi.png
├── import-from-git.png
├── import-from-ibm.png
├── import-from-k8s.png
├── import-from-kong.png
├── import-from-mulesoft.png
└── toolchain.png
├── labs
├── import-bian
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-bian.ipynb
│ ├── main.bicep
│ └── spectral.yaml
├── import-from-aws
│ ├── Petstore.json
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── get-rest-api.json
│ ├── get-rest-apis.json
│ ├── get-stage.json
│ ├── import-from-aws.ipynb
│ └── main.bicep
├── import-from-azure-apim
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-from-azure-apim.ipynb
│ └── main.bicep
├── import-from-gcp
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-from-gcp.ipynb
│ └── main.bicep
├── import-from-generic-openapi
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-from-generic-openapi.ipynb
│ ├── main.bicep
│ └── petstore.yaml
├── import-from-git
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-from-git.ipynb
│ └── main.bicep
├── import-from-ibm
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-from-ibm.ipynb
│ └── main.bicep
├── import-from-k8s
│ ├── README.MD
│ └── clean-up-resources.ipynb
├── import-from-kong
│ ├── README.MD
│ ├── clean-up-resources.ipynb
│ ├── import-from-kong.ipynb
│ └── main.bicep
└── import-from-mulesoft
│ ├── README.MD
│ ├── account_environment_list.json
│ ├── api-mgr_api_list.json
│ ├── clean-up-resources.ipynb
│ ├── import-from-mulesoft.ipynb
│ ├── main.bicep
│ └── runtime-mgr-application_describe.json
└── tools
└── delete-all-apis.ipynb
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Universal API Center Dev Container",
3 | "image": "mcr.microsoft.com/vscode/devcontainers/dotnet:8.0-jammy",
4 | "hostRequirements": {
5 | "cpus": 4
6 | },
7 | "features": {
8 | "ghcr.io/devcontainers/features/azure-cli:1": {
9 | "installBicep": true,
10 | "version": "latest"
11 | },
12 | "ghcr.io/devcontainers/features/python:1": {
13 | "installTools": true,
14 | "version": "os-provided"
15 | },
16 | "ghcr.io/stuartleeks/dev-container-features/azure-cli-persistence:0": {},
17 | "ghcr.io/azure/azure-dev/azd:0": {
18 | "version": "stable"
19 | },
20 | "ghcr.io/devcontainers/features/git:1": {
21 | "version": "latest"
22 | }
23 | },
24 | "waitFor": "onCreateCommand",
25 | "updateContentCommand": "",
26 | "postCreateCommand": "",
27 | "customizations": {
28 | "codespaces": {
29 | "openFiles": []
30 | },
31 | "vscode": {
32 | "extensions": [
33 | "ms-vscode.azure-account",
34 | "ms-azuretools.azure-dev",
35 | "ms-azuretools.vscode-apimanagement",
36 | "apidev.azure-api-center",
37 | "ms-azuretools.vscode-azurefunctions",
38 | "ms-kubernetes-tools.vscode-aks-tools",
39 | "ms-azuretools.vscode-azurecontainerapps",
40 | "ms-azuretools.vscode-azureappservice",
41 | "ms-azuretools.vscode-azurelogicapps",
42 | "ms-azuretools.vscode-azurestaticwebapps",
43 | "ms-toolsai.jupyter",
44 | "ms-python.python",
45 | "ms-dotnettools.dotnet-interactive-vscode",
46 | "github.copilot",
47 | "github.copilot-chat",
48 | "humao.rest-client",
49 | "evilz.vscode-reveal"
50 | ]
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | > Please provide us with the following information:
5 | > ---------------------------------------------------------------
6 |
7 | ### This issue is for a: (mark with an `x`)
8 | ```
9 | - [ ] bug report -> please search issues before submitting
10 | - [ ] feature request
11 | - [ ] documentation issue or request
12 | - [ ] regression (a behavior that used to work and stopped in a new release)
13 | ```
14 |
15 | ### Minimal steps to reproduce
16 | >
17 |
18 | ### Any log messages given by the failure
19 | >
20 |
21 | ### Expected/desired behavior
22 | >
23 |
24 | ### OS and Version?
25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26 |
27 | ### Versions
28 | >
29 |
30 | ### Mention any other details that might be useful
31 |
32 | > ---------------------------------------------------------------
33 | > Thanks! We'll be in touch soon.
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | * ...
4 |
5 | ## Does this introduce a breaking change?
6 |
7 | ```
8 | [ ] Yes
9 | [ ] No
10 | ```
11 |
12 | ## Pull Request Type
13 | What kind of change does this Pull Request introduce?
14 |
15 |
16 | ```
17 | [ ] Bugfix
18 | [ ] Feature
19 | [ ] Code style update (formatting, local variables)
20 | [ ] Refactoring (no functional changes, no api changes)
21 | [ ] Documentation content changes
22 | [ ] Other... Please describe:
23 | ```
24 |
25 | ## How to Test
26 | * Get the code
27 |
28 | ```
29 | git clone [repo-address]
30 | cd [repo-name]
31 | git checkout [branch-name]
32 | npm install
33 | ```
34 |
35 | * Test the code
36 |
37 | ```
38 | ```
39 |
40 | ## What to Check
41 | Verify that the following are valid
42 | * ...
43 |
44 | ## Other Information
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | .azure/
10 | .temp/
11 |
12 | labs-in-progress/
13 | params.json
14 |
15 | # Distribution / packaging
16 | .Python
17 | build/
18 | develop-eggs/
19 | dist/
20 | downloads/
21 | eggs/
22 | .eggs/
23 | lib/
24 | lib64/
25 | parts/
26 | sdist/
27 | var/
28 | wheels/
29 | pip-wheel-metadata/
30 | share/python-wheels/
31 | *.egg-info/
32 | .installed.cfg
33 | *.egg
34 | MANIFEST
35 |
36 | # PyInstaller
37 | # Usually these files are written by a python script from a template
38 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
39 | *.manifest
40 | *.spec
41 |
42 | # Installer logs
43 | pip-log.txt
44 | pip-delete-this-directory.txt
45 |
46 | # Unit test / coverage reports
47 | htmlcov/
48 | .tox/
49 | .nox/
50 | .coverage
51 | .coverage.*
52 | .cache
53 | nosetests.xml
54 | coverage.xml
55 | *.cover
56 | *.py,cover
57 | .hypothesis/
58 | .pytest_cache/
59 |
60 | # Translations
61 | *.mo
62 | *.pot
63 |
64 | # Django stuff:
65 | *.log
66 | local_settings.py
67 | db.sqlite3
68 | db.sqlite3-journal
69 |
70 | # Flask stuff:
71 | instance/
72 | .webassets-cache
73 |
74 | # Scrapy stuff:
75 | .scrapy
76 |
77 | # Sphinx documentation
78 | docs/_build/
79 |
80 | # PyBuilder
81 | target/
82 |
83 | # Jupyter Notebook
84 | .ipynb_checkpoints
85 |
86 | # IPython
87 | profile_default/
88 | ipython_config.py
89 |
90 | # pyenv
91 | .python-version
92 |
93 | # pipenv
94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
97 | # install all needed dependencies.
98 | #Pipfile.lock
99 |
100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
101 | __pypackages__/
102 |
103 | # Celery stuff
104 | celerybeat-schedule
105 | celerybeat.pid
106 |
107 | # SageMath parsed files
108 | *.sage.py
109 |
110 | # Environments
111 | .env
112 | .venv
113 | env/
114 | venv/
115 | ENV/
116 | env.bak/
117 | venv.bak/
118 |
119 | # Spyder project settings
120 | .spyderproject
121 | .spyproject
122 |
123 | # Rope project settings
124 | .ropeproject
125 |
126 | # mkdocs documentation
127 | /site
128 |
129 | # mypy
130 | .mypy_cache/
131 | .dmypy.json
132 | dmypy.json
133 |
134 | # Pyre type checker
135 | .pyre/
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to universal-api-center
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
6 |
7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | - [Code of Conduct](#coc)
16 | - [Issues and Bugs](#issue)
17 | - [Feature Requests](#feature)
18 | - [Submission Guidelines](#submit)
19 |
20 | ## Code of Conduct
21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 |
23 | ## Found an Issue?
24 | If you find a bug in the source code or a mistake in the documentation, you can help us by
25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26 | [submit a Pull Request](#submit-pr) with a fix.
27 |
28 | ## Want a Feature?
29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30 | Repository. If you would like to *implement* a new feature, please submit an issue with
31 | a proposal for your work first, to be sure that we can use it.
32 |
33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34 |
35 | ## Submission Guidelines
36 |
37 | ### Submitting an Issue
38 | Before you submit an issue, search the archive, maybe your question was already answered.
39 |
40 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
41 | Help us to maximize the effort we can spend fixing issues and adding new
42 | features, by not reporting duplicate issues. Providing the following information will increase the
43 | chances of your issue being dealt with quickly:
44 |
45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46 | * **Version** - what version is affected (e.g. 0.1.2)
47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48 | * **Browsers and Operating System** - is this a problem with all browsers?
49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
50 | * **Related Issues** - has a similar issue been reported before?
51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52 | causing the problem (line of code or commit)
53 |
54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55 |
56 | ### Submitting a Pull Request (PR)
57 | Before you submit your Pull Request (PR) consider the following guidelines:
58 |
59 | * Search the repository (https://github.com/Azure-Samples/universal-api-center/pulls) for an open or closed PR
60 | that relates to your submission. You don't want to duplicate effort.
61 |
62 | * Make your changes in a new git fork:
63 |
64 | * Commit your changes using a descriptive commit message
65 | * Push your fork to GitHub:
66 | * In GitHub, create a pull request
67 | * If we suggest changes then:
68 | * Make the required updates.
69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70 |
71 | ```shell
72 | git rebase master -i
73 | git push -f
74 | ```
75 |
76 | That's it! Thank you for your contribution!
77 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Universal API Center
2 |
3 | MIT License
4 |
5 | Copyright (c) Microsoft Corporation.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | [](https://github.com/firstcontributions/open-source-badges)
4 |
5 | ## Contents
6 | 1. [🌐 Universal API Center](#-universal-api-center)
7 | 2. [🧪 Labs](#-labs)
8 | 3. [🚀 Getting started](#-getting-started)
9 | 7. [🥇 Other Resources](#-other-resources)
10 |
11 | In the current era of digital transformation, organizations are increasingly adopting cloud-based technologies and incorporating microservice patterns, which has been a catalyst in significantly escalating the use of Application Programming Interfaces (APIs). The application of these APIs stretches across a diverse array of platforms, various environments, and different architectural designs, which suggests a gradual evolution in technological infrastructure that is crucial in sustaining a prosperous business landscape.
12 |
13 | However, organisations struggling to adapt to this API proliferation, face three major challenges:
14 | - The first is the complex task of identifying APIs due to a proliferation of platforms, API Gateways and other tools implemented by disparate teams and environments, forming a complicated maze and creating significant obstacles for modern organisations.
15 | - Secondly, each API, which enables varied functionalities across multiple environments and platforms, carries its own unique set of quality standards. This evolving and diverse API landscape spawns a complex management area for IT departments, particularly while managing multiple versions and embodiments of APIs, resembling a daunting trap requiring extensive effort to manage an overwhelming number of API variations.
16 | - Thirdly, the recent spike in security attacks directed at APIs, pose a significant concern for today's enterprises. The arrival of concealed or 'shadow' APIs introduces potential security risks, obliging companies to conduct exhaustive forensic evaluations to determine potential damage and strategize appropriate mitigation tactics. Thus, mitigating these security risks demands proper API Governance and ongoing threat monitoring capabilities to safeguard an organisation's digital ecosystem.
17 |
18 |
19 | ## 🌐 Universal API Center
20 | 
21 |
22 | 🚀 We are pleased to introduce the API Center, a new Azure service designed to address the various complexities associated with API proliferation. This ground-breaking solution will empower businesses with a reliable, seamless approach to overcoming these challenges, paving the way for enhanced operational efficiencies and productivity.
23 |
24 | The API Center provides a centralized platform for discovering, reusing, and governing all of your APIs. It establishes a structured and systematic inventory of your organization's APIs, irrespective of their type, lifecycle stage, or deployment location. Further, it accommodatively provides related information such as version specifics, API definition files, and shared metadata. Utilizing the API Center, various stakeholders within your organization including API program managers, IT administrators, application developers, and API developers can smoothly discover, reuse, and govern APIs.
25 |
26 | ### Benefits
27 | - Having a robust inventory of APIs within an organization's framework is crucial as it fosters effective communication and collaboration between API program managers and developers. This not only amplifies the quality and reusability of APIs but also amplifies their security and compliance. Ultimately, this strategic approach leads to an advantageous uptick in developer productivity.
28 | - Enhancing your organization's API governance offers a crucial advantage. It allows API program managers and IT administrators to maintain comprehensive oversight of the API creation and utilization within their organization. This enhanced visibility promotes adherence to organizational standards by facilitating the definition of custom metadata and the analysis of API definitions. This in turn enables the enforcement of conformance to API style guidelines, thereby improving the overall API management.
29 | - API Center enhances API discovery, enabling organizations to promote API reuse and optimize developer productivity by assisting both program managers and developers in identifying API inventory and filtering with both built-in and bespoke metadata properties. Moreover, the API Center expedites API consumption to further boost developer efficiency, safeguarding secure and organizationally compliant usage of APIs.
30 |
31 | To expedite the realization of the above benefits, we have constructed a variety of labs demonstrating the seamless cataloguing of APIs from diverse gateways and sources. This step is integral in our goal to establish a truly **Universal API center**.
32 |
33 |
34 | ## 🧪 Labs
35 |
36 | The labs, structured as Jupyter notebooks, offer thorough guidance on utilizing PowerShell scripts in conjunction with Azure CLI commands. These comprehensive instructions cover diverse functionalities, including importing, and discovering APIs.
37 |
38 | > [!TIP]
39 | > You can apply the supplied Powershell scripts across various platforms, including Windows, Linux, and Mac, to construct automation workflows, continuous integration, and continuous delivery pipelines, among other procedures. This facilitates the enhancement of productivity and efficiency within your operations.
40 |
41 | | | | | |
42 | | ---- | ----- | ----------- | -- |
43 | | [Import from generic OpenAPI](labs/import-from-generic-openapi/import-from-generic-openapi.ipynb) | [](labs/import-from-generic-openapi/import-from-generic-openapi.ipynb) | Playground to experiment importing APIs in the OpenAPI specification into API Center. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Azure CLI]((https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest)) to import the APIs. | [💬](../../issues/2 "Discussion") |
44 | | [Import from Azure API Management](labs/import-from-azure-apim/import-from-azure-apim.ipynb) | [](labs/import-from-azure-apim/import-from-azure-apim.ipynb) | Playground to experiment importing APIs from Azure APIM into API Center. We start by creating APIM and API Center instances using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Azure CLI]((https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest)) to import the APIs from APIM. | [💬](../../issues/3 "Discussion") |
45 | | [Import from Amazon API Gateway](labs/import-from-aws/import-from-aws.ipynb) | [](labs/import-from-aws/import-from-aws.ipynb) | Playground to experiment importing APIs from Amazon API Gateway. We will use the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) to export the APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center. | [💬](../../issues/4 "Discussion") |
46 | | [Import from Apigee](labs/import-from-gcp/import-from-gcp.ipynb) | [](labs/import-from-gcp/import-from-gcp.ipynb) | Playground to experiment importing APIs from Apigee. We will use the [GCP CLI](https://cloud.google.com/sdk/docs/install-sdk) to export the Apigee APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center. | [💬](../../issues/5 "Discussion") |
47 | | [Import from Kong](labs/import-from-kong/import-from-kong.ipynb) | [](labs/import-from-kong/import-from-kong.ipynb) | Playground to experiment importing APIs from Kong API Gateway. We will use the [Kong Admin API](https://docs.konghq.com/gateway/api/admin-oss/latest) to export Kong services and import them into API Center. | [💬](../../issues/6 "Discussion") |
48 | | [Import from Mulesoft](labs/import-from-mulesoft/import-from-mulesoft.ipynb) | [](labs/import-from-mulesoft/import-from-mulesoft.ipynb) | Playground to experiment importing APIs from the MuleSoft Anypoint platform. We will use the [Anypoint Platform CLI](https://docs.mulesoft.com/anypoint-cli/latest/) to export the APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center. | [💬](../../issues/7 "Discussion") |
49 | | [Import from IBM](labs/import-from-ibm/import-from-ibm.ipynb) | [](labs/import-from-ibm/import-from-ibm.ipynb) | Playground to experiment bulk importing APIs from IBM API Connect into API Center | |
50 | | [Import from Git](labs/import-from-git/import-from-git.ipynb) | [](labs/import-from-git/import-from-git.ipynb) | Playground to experiment importing APIs in the OpenAPI specification into API Center by crawling Git repositories. | [💬](../../issues/9 "Discussion") |
51 | | [Import BIAN](labs/import-bian/import-bian.ipynb) | [](labs/import-bian/import-bian.ipynb) | Playground to experiment importing Banking Industry Architecture Network (BIAN) APIs from [their GitHub repo](https://github.com/bian-official/public). | |
52 |
53 |
54 |
55 |
56 |
57 | > [!TIP]
58 | > Kindly use [the feedback discussion](../../discussions/1) so that we can continuously improve with your experiences, suggestions, ideas or lab requests.
59 |
60 | ## 🚀 Getting Started
61 |
62 | [](https://codespaces.new/Azure-Samples/universal-api-center/tree/main)
63 |
64 |
65 | ### Prerequisites
66 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
67 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
68 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
69 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
70 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
71 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
72 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
73 |
74 | ### Quickstart
75 | 1. Clone this repo and configure your local machine with the prerequisites. Or just create a [GitHub Codespace](https://codespaces.new/Azure-Samples/universal-api-center/tree/main) and run it on the browser or in VS Code.
76 | 2. Navigate through the available labs and select one that best suits your needs. For starters we recommend the [import from generic OpenAPI](labs/import-from-generic-openapi/import-from-generic-openapi.ipynb).
77 | 3. Open the notebook and run the provided steps.
78 | 4. Tailor the experiment according to your requirements. If you wish to contribute to our collective work, we would appreciate your [submission of a pull request](CONTRIBUTING.MD).
79 |
80 | > [!NOTE]
81 | > 🪲 Please feel free to open a new [issue](../../issues/new) if you find something that should be fixed or enhanced.
82 |
83 | ## 🥇 Other resources
84 |
85 | - [API Center Overview video](https://www.youtube.com/watch?v=Y9K3Fx2TpCo)
86 | - [API Center documentation](https://learn.microsoft.com/en-us/azure/api-center/)
87 | - [Self-host Your Azure API Center Portal](https://github.com/Azure/APICenter-Portal-Starter)
88 | - [Analyze your API Specs with Azure API Center](https://github.com/Azure/APICenter-Analyzer)
89 | - [Govern SAP APIs living in various API Management gateways in a single place with Azure API Center](https://community.sap.com/t5/technology-blogs-by-members/govern-sap-apis-living-in-various-api-management-gateways-in-a-single-place/ba-p/13682483)
90 |
91 | > We believe that there may be valuable content that we are currently unaware of. We would greatly appreciate any suggestions or recommendations to enhance this list.
92 |
93 | ### 🌐 WW GBB initiative
94 |
95 | 
96 |
97 | ### Disclaimer
98 | > [!IMPORTANT]
99 | > This software is provided for demonstration purposes only. It is not intended to be relied upon for any purpose. The creators of this software make no representations or warranties of any kind, express or implied, about the completeness, accuracy, reliability, suitability or availability with respect to the software or the information, products, services, or related graphics contained in the software for any purpose. Any reliance you place on such information is therefore strictly at your own risk.
100 |
101 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
102 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
103 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
104 |
105 | Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies.
106 |
107 |
--------------------------------------------------------------------------------
/images/api-center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/api-center.png
--------------------------------------------------------------------------------
/images/gbb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/gbb.png
--------------------------------------------------------------------------------
/images/import-bian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-bian.png
--------------------------------------------------------------------------------
/images/import-from-aws.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-aws.png
--------------------------------------------------------------------------------
/images/import-from-azure-apim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-azure-apim.png
--------------------------------------------------------------------------------
/images/import-from-gcp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-gcp.png
--------------------------------------------------------------------------------
/images/import-from-generic-openapi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-generic-openapi.png
--------------------------------------------------------------------------------
/images/import-from-git.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-git.png
--------------------------------------------------------------------------------
/images/import-from-ibm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-ibm.png
--------------------------------------------------------------------------------
/images/import-from-k8s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-k8s.png
--------------------------------------------------------------------------------
/images/import-from-kong.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-kong.png
--------------------------------------------------------------------------------
/images/import-from-mulesoft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/import-from-mulesoft.png
--------------------------------------------------------------------------------
/images/toolchain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/universal-api-center/21e4e9280a4d3dc5c6558717aa69abe6bfbb4671/images/toolchain.png
--------------------------------------------------------------------------------
/labs/import-bian/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import the Banking Industry Architecture Network (BIAN) APIs
4 | 
5 |
6 | Playground to experiment importing BIAN APIs from the GitHub repo.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Prerequisites
11 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
12 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
13 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
14 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
15 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
16 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
17 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
18 | - Install [Spectral CLI](https://github.com/stoplightio/spectral)
19 |
20 | ### 🚀 Get started
21 | Proceed by opening the [Jupyter notebook](import-bian.ipynb), and follow the steps provided.
22 |
23 | ### 🗑️ Clean up resources
24 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
25 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-bian/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-bian/import-bian.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# API Center ❤️ all APIs\n",
8 | "\n",
9 | "## Import the Banking Industry Architecture Network (BIAN) APIs\n",
10 | "\n",
11 | "\n",
12 | "Playground to experiment importing BIAN APIs from the GitHub repo.\n",
13 | "\n",
14 | "💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.\n",
15 | "\n",
16 | "### Prerequisites\n",
17 | "- Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)\n",
18 | "- Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)\n",
19 | "- Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace\n",
20 | "- Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)\n",
21 | "- Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.\n",
22 | "- [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions\n",
23 | "- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)\n",
24 | "- Install [Spectral CLI](https://github.com/stoplightio/spectral)\n"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "### 0️⃣ Initialize notebook variables\n",
32 | "\n",
33 | "- Resources will be suffixed by a unique string based on your subscription id\n",
34 | "- Adjust the APIC location parameter according your preferences and [region availability.](https://learn.microsoft.com/en-us/azure/api-center/overview#available-regions) \n"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {
41 | "dotnet_interactive": {
42 | "language": "pwsh"
43 | },
44 | "polyglot_notebook": {
45 | "kernelName": "pwsh"
46 | },
47 | "vscode": {
48 | "languageId": "polyglot-notebook"
49 | }
50 | },
51 | "outputs": [],
52 | "source": [
53 | "\n",
54 | "$sourceRepo = \"https://github.com/bian-official/public\"\n",
55 | "$maxAPIsToImport = 10\n",
56 | "\n",
57 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
58 | "$resourceGroupName = \"lab-$deploymentName\" # change the name to match your naming style\n",
59 | "$resourceGroupLocation = \"westeurope\"\n",
60 | "$apicResourceNamePrefix = \"apic\"\n",
61 | "$apicResourceSku = \"free\"\n",
62 | "$apicResourceTags = @{\n",
63 | " \"lab\" = $deploymentName\n",
64 | "}\n",
65 | "\n",
66 | "# the following metadata will be created during the deployment\n",
67 | "$metadata = @(\n",
68 | ")\n",
69 | "\n",
70 | "# the following environment(s) will be created during the deployment\n",
71 | "$environments = @(\n",
72 | ")\n",
73 | "\n",
74 | "\n",
75 | "Write-Output \"✅ Variables initialized ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "### 1️⃣ Create the Azure Resource Group\n",
83 | "All resources deployed in this lab will be created in the specified resource group. Skip this step if you want to use an existing resource group."
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": null,
89 | "metadata": {
90 | "dotnet_interactive": {
91 | "language": "pwsh"
92 | },
93 | "polyglot_notebook": {
94 | "kernelName": "pwsh"
95 | },
96 | "vscode": {
97 | "languageId": "polyglot-notebook"
98 | }
99 | },
100 | "outputs": [],
101 | "source": [
102 | "$resourceGroupOutput = az group create --name $resourceGroupName --location $resourceGroupLocation\n",
103 | "\n",
104 | "if ($LASTEXITCODE -ne 0) {\n",
105 | " Write-Output $resourceGroupOutput\n",
106 | "} else {\n",
107 | " Write-Output \"✅ Azure Resource Grpup $resourceGroupName created ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
108 | "}"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "### 2️⃣ Create deployment using 🦾 Bicep\n",
116 | "\n",
117 | "This lab uses [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declarative define all the resources that will be deployed. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations. "
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "metadata": {
124 | "dotnet_interactive": {
125 | "language": "pwsh"
126 | },
127 | "polyglot_notebook": {
128 | "kernelName": "pwsh"
129 | },
130 | "vscode": {
131 | "languageId": "polyglot-notebook"
132 | }
133 | },
134 | "outputs": [],
135 | "source": [
136 | "$bicepParameters = @{\n",
137 | " \"`$schema\" = \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\"\n",
138 | " \"contentVersion\" = \"1.0.0.0\"\n",
139 | " \"parameters\" = @{\n",
140 | " \"apicResourceNamePrefix\" = @{ \"value\" = $apicResourceNamePrefix }\n",
141 | " \"apicResourceTags\" = @{ \"value\" = $apicResourceTags }\n",
142 | " \"apicMetadataSchema\" = @{ \"value\" = $metadata }\n",
143 | " \"apicEnvironments\" = @{ \"value\" = $environments }\n",
144 | " }\n",
145 | "}\n",
146 | "\n",
147 | "$bicepParametersJson = ConvertTo-Json -InputObject $bicepParameters -Depth 10\n",
148 | "Set-Content -Path \"params.json\" -Value $bicepParametersJson\n",
149 | "\n",
150 | "# Execute the Azure CLI command to create the deployment\n",
151 | "az deployment group create --name $deploymentName --resource-group $resourceGroupName --template-file \"main.bicep\" --parameters \"params.json\"\n",
152 | "\n"
153 | ]
154 | },
155 | {
156 | "cell_type": "markdown",
157 | "metadata": {},
158 | "source": [
159 | "### 3️⃣ Get the deployment outputs\n",
160 | "\n",
161 | "We will set the `apicResourceName` variable with the value that was returned from the deployment "
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": null,
167 | "metadata": {
168 | "dotnet_interactive": {
169 | "language": "pwsh"
170 | },
171 | "polyglot_notebook": {
172 | "kernelName": "pwsh"
173 | },
174 | "vscode": {
175 | "languageId": "polyglot-notebook"
176 | }
177 | },
178 | "outputs": [],
179 | "source": [
180 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apicResourceName.value -o json\n",
181 | "if ($LASTEXITCODE -ne 0) {\n",
182 | " Write-Output $deploymentOutput\n",
183 | "} else {\n",
184 | " $apicResourceName = $deploymentOutput | ConvertFrom-Json\n",
185 | "}\n",
186 | "Write-Output \"👉🏻 API Center name: $apicResourceName\""
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "### 4️⃣ Clone the repo\n",
194 | "\n",
195 | "Creates a local copy of the specific repository or branch within a repository.\n"
196 | ]
197 | },
198 | {
199 | "cell_type": "code",
200 | "execution_count": null,
201 | "metadata": {
202 | "dotnet_interactive": {
203 | "language": "pwsh"
204 | },
205 | "polyglot_notebook": {
206 | "kernelName": "pwsh"
207 | },
208 | "vscode": {
209 | "languageId": "polyglot-notebook"
210 | }
211 | },
212 | "outputs": [],
213 | "source": [
214 | "git clone $sourceRepo \".temp\""
215 | ]
216 | },
217 | {
218 | "cell_type": "markdown",
219 | "metadata": {},
220 | "source": [
221 | "### 5️⃣ Crawl APIs and register each one of them in API Center\n",
222 | "\n",
223 | "[Registers](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-register) each valid API in the cloned repo."
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": null,
229 | "metadata": {
230 | "dotnet_interactive": {
231 | "language": "pwsh"
232 | },
233 | "polyglot_notebook": {
234 | "kernelName": "pwsh"
235 | },
236 | "vscode": {
237 | "languageId": "polyglot-notebook"
238 | }
239 | },
240 | "outputs": [],
241 | "source": [
242 | "$results = @()\n",
243 | "\n",
244 | "$files = Get-ChildItem -Path \".temp\\release12.0.0\\semantic-apis\\oas3\\yamls\" -Recurse -File\n",
245 | "\n",
246 | "$counter = 0\n",
247 | "foreach ($file in $files) {\n",
248 | " if ($file.Extension -eq \".yaml\" || $file.Extension -eq \".yml\" || $file.Extension -eq \".json\") {\n",
249 | " $fileSize = $file.Length\n",
250 | " $filePath = $file.FullName\n",
251 | " $lintintProblemsJson = spectral lint $filePath --ruleset spectral.yaml -f json \n",
252 | " $lintintProblems = $lintintProblemsJson | ConvertFrom-Json\n",
253 | " $lintingErrors = 0\n",
254 | " $lintingWarnings = 0\n",
255 | " foreach ($problem in $lintintProblems) {\n",
256 | " if ($problem.severity -eq 0) {\n",
257 | " $lintingErrors++\n",
258 | " } elseif ($problem.severity -eq 1) {\n",
259 | " $lintingWarnings++\n",
260 | " }\n",
261 | " }\n",
262 | " Write-Output \"👉🏻 Registering: $filePath\"\n",
263 | " $registerOutput = az apic api register -g $resourceGroupName -n $apicResourceName -l $filePath 2>&1\n",
264 | " $registeredAPI = [ordered] @{ \n",
265 | " Name = $file.Name \n",
266 | " File = $file.FullName \n",
267 | " Extension = $file.Extension \n",
268 | " Size = $file.Length\n",
269 | " Errors = $lintingErrors\n",
270 | " Warnings = $lintingWarnings\n",
271 | " API = if ($registerOutput -match \"API was created successfully\") {\"OK\"} else {\"ERROR\"}\n",
272 | " Version = if ($registerOutput -match \"API version was created successfully\") {\"OK\"} else {\"ERROR\"}\n",
273 | " Definition = if ($registerOutput -match \"API specification was created successfully\") {\"OK\"} else {\"ERROR\"}\n",
274 | " Output = $registerOutput | Out-String\n",
275 | " } \n",
276 | " $results += New-Object PSObject -Property $registeredAPI\n",
277 | " $counter++\n",
278 | " if ($counter -ge $maxAPIsToImport) {\n",
279 | " Write-Output \"🚫 Max APIs to import reached. Done for now.\"\n",
280 | " break\n",
281 | " }\n",
282 | " }\n",
283 | "}\n",
284 | "Write-Output \"✅ $counter APIs imported.\"\n",
285 | "\n",
286 | "$results | export-csv -Path .temp/result.csv -NoTypeInformation -Delimiter \";\"\n"
287 | ]
288 | },
289 | {
290 | "cell_type": "markdown",
291 | "metadata": {},
292 | "source": [
293 | "### 7️⃣ Discover the APIs that were just imported\n",
294 | "\n",
295 | "You can discover the APIs with fhe following methods:\n",
296 | "- With the Azure Portal\n",
297 | "- With the [self-hosted API Center Portal](https://learn.microsoft.com/en-us/azure/api-center/enable-api-center-portal)\n",
298 | "- With the [VS Code extension](https://learn.microsoft.com/en-us/azure/api-center/use-vscode-extension-copilot) that is integrated with GitHub Copilot Chat.\n",
299 | "- With the CLI, the service REST API and more\n",
300 | "\n",
301 | "Here we will use the [list command](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-list) to display the APIs that we have just imported. \n"
302 | ]
303 | },
304 | {
305 | "cell_type": "code",
306 | "execution_count": null,
307 | "metadata": {
308 | "dotnet_interactive": {
309 | "language": "pwsh"
310 | },
311 | "polyglot_notebook": {
312 | "kernelName": "pwsh"
313 | },
314 | "vscode": {
315 | "languageId": "polyglot-notebook"
316 | }
317 | },
318 | "outputs": [],
319 | "source": [
320 | "az apic api list -g $resourceGroupName -n $apicResourceName --query \"[].{Name:name, Title:title, ContactEmail:contacts[0].email}\" -o table"
321 | ]
322 | },
323 | {
324 | "cell_type": "markdown",
325 | "metadata": {},
326 | "source": [
327 | "### 🗑️ Clean up resources\n",
328 | "\n",
329 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n",
330 | "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that."
331 | ]
332 | }
333 | ],
334 | "metadata": {
335 | "kernelspec": {
336 | "display_name": ".NET (C#)",
337 | "language": "C#",
338 | "name": ".net-csharp"
339 | },
340 | "language_info": {
341 | "codemirror_mode": {
342 | "name": "ipython",
343 | "version": 3
344 | },
345 | "file_extension": ".py",
346 | "mimetype": "text/x-python",
347 | "name": "python",
348 | "nbconvert_exporter": "python",
349 | "pygments_lexer": "ipython3",
350 | "version": "3.11.9"
351 | },
352 | "polyglot_notebook": {
353 | "kernelInfo": {
354 | "defaultKernelName": "csharp",
355 | "items": [
356 | {
357 | "aliases": [],
358 | "name": "csharp"
359 | }
360 | ]
361 | }
362 | }
363 | },
364 | "nbformat": 4,
365 | "nbformat_minor": 2
366 | }
367 |
--------------------------------------------------------------------------------
/labs/import-bian/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-bian/spectral.yaml:
--------------------------------------------------------------------------------
1 | extends: spectral:oas
2 |
3 |
--------------------------------------------------------------------------------
/labs/import-from-aws/Petstore.json:
--------------------------------------------------------------------------------
1 | {
2 | "openapi" : "3.0.1",
3 | "info" : {
4 | "title" : "PetStore",
5 | "description" : "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints",
6 | "version" : "2024-05-02"
7 | },
8 | "servers" : [ {
9 | "url" : "https://2q3nwrw1r0.execute-api.eu-north-1.amazonaws.com/{basePath}",
10 | "variables" : {
11 | "basePath" : {
12 | "default" : "production"
13 | }
14 | }
15 | } ],
16 | "paths" : {
17 | "/pets" : {
18 | "get" : {
19 | "parameters" : [ {
20 | "name" : "type",
21 | "in" : "query",
22 | "schema" : {
23 | "type" : "string"
24 | }
25 | }, {
26 | "name" : "page",
27 | "in" : "query",
28 | "schema" : {
29 | "type" : "string"
30 | }
31 | } ],
32 | "responses" : {
33 | "200" : {
34 | "description" : "200 response",
35 | "headers" : {
36 | "Access-Control-Allow-Origin" : {
37 | "schema" : {
38 | "type" : "string"
39 | }
40 | }
41 | },
42 | "content" : {
43 | "application/json" : {
44 | "schema" : {
45 | "$ref" : "#/components/schemas/Pets"
46 | }
47 | }
48 | }
49 | }
50 | }
51 | },
52 | "post" : {
53 | "operationId" : "CreatePet",
54 | "requestBody" : {
55 | "content" : {
56 | "application/json" : {
57 | "schema" : {
58 | "$ref" : "#/components/schemas/NewPet"
59 | }
60 | }
61 | },
62 | "required" : true
63 | },
64 | "responses" : {
65 | "200" : {
66 | "description" : "200 response",
67 | "headers" : {
68 | "Access-Control-Allow-Origin" : {
69 | "schema" : {
70 | "type" : "string"
71 | }
72 | }
73 | },
74 | "content" : {
75 | "application/json" : {
76 | "schema" : {
77 | "$ref" : "#/components/schemas/NewPetResponse"
78 | }
79 | }
80 | }
81 | }
82 | }
83 | },
84 | "options" : {
85 | "responses" : {
86 | "200" : {
87 | "description" : "200 response",
88 | "headers" : {
89 | "Access-Control-Allow-Origin" : {
90 | "schema" : {
91 | "type" : "string"
92 | }
93 | },
94 | "Access-Control-Allow-Methods" : {
95 | "schema" : {
96 | "type" : "string"
97 | }
98 | },
99 | "Access-Control-Allow-Headers" : {
100 | "schema" : {
101 | "type" : "string"
102 | }
103 | }
104 | },
105 | "content" : {
106 | "application/json" : {
107 | "schema" : {
108 | "$ref" : "#/components/schemas/Empty"
109 | }
110 | }
111 | }
112 | }
113 | }
114 | }
115 | },
116 | "/pets/{petId}" : {
117 | "get" : {
118 | "operationId" : "GetPet",
119 | "parameters" : [ {
120 | "name" : "petId",
121 | "in" : "path",
122 | "required" : true,
123 | "schema" : {
124 | "type" : "string"
125 | }
126 | } ],
127 | "responses" : {
128 | "200" : {
129 | "description" : "200 response",
130 | "headers" : {
131 | "Access-Control-Allow-Origin" : {
132 | "schema" : {
133 | "type" : "string"
134 | }
135 | }
136 | },
137 | "content" : {
138 | "application/json" : {
139 | "schema" : {
140 | "$ref" : "#/components/schemas/Pet"
141 | }
142 | }
143 | }
144 | }
145 | }
146 | },
147 | "options" : {
148 | "parameters" : [ {
149 | "name" : "petId",
150 | "in" : "path",
151 | "required" : true,
152 | "schema" : {
153 | "type" : "string"
154 | }
155 | } ],
156 | "responses" : {
157 | "200" : {
158 | "description" : "200 response",
159 | "headers" : {
160 | "Access-Control-Allow-Origin" : {
161 | "schema" : {
162 | "type" : "string"
163 | }
164 | },
165 | "Access-Control-Allow-Methods" : {
166 | "schema" : {
167 | "type" : "string"
168 | }
169 | },
170 | "Access-Control-Allow-Headers" : {
171 | "schema" : {
172 | "type" : "string"
173 | }
174 | }
175 | },
176 | "content" : {
177 | "application/json" : {
178 | "schema" : {
179 | "$ref" : "#/components/schemas/Empty"
180 | }
181 | }
182 | }
183 | }
184 | }
185 | }
186 | },
187 | "/" : {
188 | "get" : {
189 | "responses" : {
190 | "200" : {
191 | "description" : "200 response",
192 | "headers" : {
193 | "Content-Type" : {
194 | "schema" : {
195 | "type" : "string"
196 | }
197 | }
198 | },
199 | "content" : { }
200 | }
201 | }
202 | }
203 | }
204 | },
205 | "components" : {
206 | "schemas" : {
207 | "Pets" : {
208 | "type" : "array",
209 | "items" : {
210 | "$ref" : "#/components/schemas/Pet"
211 | }
212 | },
213 | "Empty" : {
214 | "type" : "object"
215 | },
216 | "NewPetResponse" : {
217 | "type" : "object",
218 | "properties" : {
219 | "pet" : {
220 | "$ref" : "#/components/schemas/Pet"
221 | },
222 | "message" : {
223 | "type" : "string"
224 | }
225 | }
226 | },
227 | "Pet" : {
228 | "type" : "object",
229 | "properties" : {
230 | "id" : {
231 | "type" : "integer"
232 | },
233 | "type" : {
234 | "type" : "string"
235 | },
236 | "price" : {
237 | "type" : "number"
238 | }
239 | }
240 | },
241 | "NewPet" : {
242 | "type" : "object",
243 | "properties" : {
244 | "type" : {
245 | "$ref" : "#/components/schemas/PetType"
246 | },
247 | "price" : {
248 | "type" : "number"
249 | }
250 | }
251 | },
252 | "PetType" : {
253 | "type" : "string",
254 | "enum" : [ "dog", "cat", "fish", "bird", "gecko" ]
255 | }
256 | }
257 | }
258 | }
--------------------------------------------------------------------------------
/labs/import-from-aws/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Amazon API Gateway
4 | 
5 |
6 | Playground to experiment importing APIs from Amazon API Gateway. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) to export the APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Learning Objectives - Upon completing this lab, you should be able to:
11 | - Deploy Azure API Center using Bicep.
12 | - Configure the API Center metadata scheme for APIs, Environments and Deployments.
13 | - Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).
14 | - Register APIs using the OpenAPI spec exported from AWS API Gateway.
15 | - Create deployments for each AWS API Gateway stage.
16 | - Search and discover the APIs registered in API Center.
17 |
18 | ### Prerequisites
19 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
20 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
21 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
22 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
23 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
24 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
25 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
26 | - Install or update to the latest [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
27 | - [Setup](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html) the AWS CLI to interact with AWS services
28 |
29 | ### 🚀 Get started
30 | Proceed by opening the [Jupyter notebook](import-from-aws.ipynb), and follow the steps provided.
31 |
32 | ### 🗑️ Clean up resources
33 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
34 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-aws/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-aws/get-rest-api.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "2q3nwrw1r0",
3 | "name": "PetStore",
4 | "description": "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints",
5 | "createdDate": "2024-05-02T21:54:38+01:00",
6 | "apiKeySource": "HEADER",
7 | "endpointConfiguration": {
8 | "types": [
9 | "REGIONAL"
10 | ]
11 | },
12 | "tags": {
13 | "dataClassification": "Confidential",
14 | "department": "HR"
15 | },
16 | "disableExecuteApiEndpoint": false,
17 | "rootResourceId": "o66v41060e"
18 | }
--------------------------------------------------------------------------------
/labs/import-from-aws/get-rest-apis.json:
--------------------------------------------------------------------------------
1 | {
2 | "items": [
3 | {
4 | "id": "2q3nwrw1r0",
5 | "name": "PetStore",
6 | "description": "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints",
7 | "createdDate": "2024-05-02T21:54:38+01:00",
8 | "apiKeySource": "HEADER",
9 | "endpointConfiguration": {
10 | "types": [
11 | "REGIONAL"
12 | ]
13 | },
14 | "disableExecuteApiEndpoint": false,
15 | "rootResourceId": "o66v41060e"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/labs/import-from-aws/get-stage.json:
--------------------------------------------------------------------------------
1 | {
2 | "deploymentId": "g97923",
3 | "stageName": "production",
4 | "description": "Production Stage",
5 | "cacheClusterEnabled": false,
6 | "cacheClusterSize": "0.5",
7 | "cacheClusterStatus": "NOT_AVAILABLE",
8 | "methodSettings": {
9 | "*/*": {
10 | "metricsEnabled": false,
11 | "dataTraceEnabled": false,
12 | "throttlingBurstLimit": -1,
13 | "throttlingRateLimit": -1.0,
14 | "cachingEnabled": false,
15 | "cacheTtlInSeconds": 300,
16 | "cacheDataEncrypted": false,
17 | "requireAuthorizationForCacheControl": true,
18 | "unauthorizedCacheControlHeaderStrategy": "SUCCEED_WITH_RESPONSE_HEADER"
19 | }
20 | },
21 | "tracingEnabled": false,
22 | "createdDate": "2024-05-02T21:56:07+01:00",
23 | "lastUpdatedDate": "2024-05-02T23:02:23+01:00"
24 | }
--------------------------------------------------------------------------------
/labs/import-from-aws/import-from-aws.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# API Center ❤️ all APIs\n",
8 | "\n",
9 | "## Import from Amazon API Gateway\n",
10 | "\n",
11 | "\n",
12 | "Playground to experiment importing APIs from Amazon API Gateway. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) to export the APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center.\n",
13 | "\n",
14 | "💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.\n",
15 | "\n",
16 | "### Learning Objectives - Upon completing this lab, you should be able to:\n",
17 | "- Deploy Azure API Center using Bicep.\n",
18 | "- Configure the API Center metadata scheme for APIs, Environments and Deployments.\n",
19 | "- Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).\n",
20 | "- Register APIs using the OpenAPI spec exported from AWS API Gateway.\n",
21 | "- Create deployments for each AWS API Gateway stage. \n",
22 | "- Search and discover the APIs registered in API Center.\n",
23 | "\n",
24 | "### Prerequisites\n",
25 | "- Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)\n",
26 | "- Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)\n",
27 | "- Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace\n",
28 | "- Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)\n",
29 | "- Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.\n",
30 | "- [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions\n",
31 | "- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)\n",
32 | "- Install or update to the latest [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)\n",
33 | "- [Setup](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html) the AWS CLI to interact with AWS services"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "### 0️⃣ Initialize notebook variables\n",
41 | "\n",
42 | "- Resources will be suffixed by a unique string based on your subscription id\n",
43 | "- Adjust the APIC location parameter according your preferences and [region availability.](https://learn.microsoft.com/en-us/azure/api-center/overview#available-regions) \n"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "dotnet_interactive": {
51 | "language": "pwsh"
52 | },
53 | "polyglot_notebook": {
54 | "kernelName": "pwsh"
55 | },
56 | "vscode": {
57 | "languageId": "polyglot-notebook"
58 | }
59 | },
60 | "outputs": [],
61 | "source": [
62 | "\n",
63 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
64 | "$resourceGroupName = \"lab-$deploymentName\" # change the name to match your naming style\n",
65 | "$resourceGroupLocation = \"westeurope\"\n",
66 | "$apicResourceNamePrefix = \"apic\"\n",
67 | "$apicResourceSku = \"free\"\n",
68 | "$apicResourceTags = @{\n",
69 | " \"lab\" = $deploymentName\n",
70 | "}\n",
71 | "\n",
72 | "# the following metadata will be created during the deployment\n",
73 | "$metadata = @(\n",
74 | " @{\n",
75 | " \"name\" = 'createdDate'\n",
76 | " \"schema\" = '{\"title\":\"createdDate\",\"description\":\"Date when the API was created\",\"type\":\"string\"}'\n",
77 | " \"assignedTo\" = @(\n",
78 | " @{\n",
79 | " \"entity\" = 'api'\n",
80 | " \"required\" = $false\n",
81 | " },\n",
82 | " @{\n",
83 | " \"entity\" = 'deployment'\n",
84 | " \"required\" = $false\n",
85 | " }\n",
86 | " )\n",
87 | " },\n",
88 | " @{\n",
89 | " \"name\" = 'rootResourceId'\n",
90 | " \"schema\" = '{\"title\":\"rootResourceId\",\"description\":\"API Gateway resource id\",\"type\":\"string\"}'\n",
91 | " \"assignedTo\" = @(\n",
92 | " @{\n",
93 | " \"entity\" = 'api'\n",
94 | " \"required\" = $false\n",
95 | " }\n",
96 | " )\n",
97 | " },\n",
98 | " @{\n",
99 | " \"name\" = 'dataClassification'\n",
100 | " \"schema\" = '{\"title\":\"dataClassification\",\"description\":\"Classification of the Data that will transit in the API\",\"type\":\"string\"}'\n",
101 | " \"assignedTo\" = @(\n",
102 | " @{\n",
103 | " \"entity\" = 'api'\n",
104 | " \"required\" = $false\n",
105 | " }\n",
106 | " )\n",
107 | " },\n",
108 | " @{\n",
109 | " \"name\" = 'department'\n",
110 | " \"schema\" = '{\"title\":\"department\",\"description\":\"Department associated with the API\",\"type\":\"string\"}'\n",
111 | " \"assignedTo\" = @(\n",
112 | " @{\n",
113 | " \"entity\" = 'api'\n",
114 | " \"required\" = $false\n",
115 | " }\n",
116 | " )\n",
117 | " }\n",
118 | ")\n",
119 | "\n",
120 | "# the following environment(s) will be created during the deployment\n",
121 | "$environments = @(\n",
122 | " @{\n",
123 | " \"title\" = 'production'\n",
124 | " \"kind\" = 'production'\n",
125 | " \"description\" = 'Production Stage'\n",
126 | " \"server\" = @{\n",
127 | " \"type\" = 'AWS API Gateway' \n",
128 | " \"managementPortalUri\" = 'https://console.aws.amazon.com/apigateway/'\n",
129 | " }\n",
130 | " \"onboarding\" = @{\n",
131 | " \"developerPortalUri\" = ''\n",
132 | " \"instructions\" = ''\n",
133 | " }\n",
134 | " \"customProperties\" = @{ \n",
135 | " }\n",
136 | " },\n",
137 | " @{\n",
138 | " \"title\" = 'development'\n",
139 | " \"kind\" = 'development'\n",
140 | " \"description\" = 'Development Stage'\n",
141 | " \"server\" = @{\n",
142 | " \"type\" = 'AWS API Gateway' \n",
143 | " \"managementPortalUri\" = 'https://console.aws.amazon.com/apigateway/'\n",
144 | " }\n",
145 | " \"onboarding\" = @{\n",
146 | " \"developerPortalUri\" = ''\n",
147 | " \"instructions\" = ''\n",
148 | " }\n",
149 | " \"customProperties\" = @{ \n",
150 | " }\n",
151 | " }\n",
152 | ")\n",
153 | "\n",
154 | "Write-Output \"✅ Variables initialized ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n"
155 | ]
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "### 1️⃣ Create the Azure Resource Group\n",
162 | "All resources deployed in this lab will be created in the specified resource group. Skip this step if you want to use an existing resource group."
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {
169 | "dotnet_interactive": {
170 | "language": "pwsh"
171 | },
172 | "polyglot_notebook": {
173 | "kernelName": "pwsh"
174 | },
175 | "vscode": {
176 | "languageId": "polyglot-notebook"
177 | }
178 | },
179 | "outputs": [],
180 | "source": [
181 | "$resourceGroupOutput = az group create --name $resourceGroupName --location $resourceGroupLocation\n",
182 | "\n",
183 | "if ($LASTEXITCODE -ne 0) {\n",
184 | " Write-Output $resourceGroupOutput\n",
185 | "} else {\n",
186 | " Write-Output \"✅ Azure Resource Grpup $resourceGroupName created ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
187 | "}"
188 | ]
189 | },
190 | {
191 | "cell_type": "markdown",
192 | "metadata": {},
193 | "source": [
194 | "### 2️⃣ Create deployment using 🦾 Bicep\n",
195 | "\n",
196 | "This lab uses [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declarative define all the resources that will be deployed. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations. "
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "dotnet_interactive": {
204 | "language": "pwsh"
205 | },
206 | "polyglot_notebook": {
207 | "kernelName": "pwsh"
208 | },
209 | "vscode": {
210 | "languageId": "polyglot-notebook"
211 | }
212 | },
213 | "outputs": [],
214 | "source": [
215 | "$bicepParameters = @{\n",
216 | " \"`$schema\" = \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\"\n",
217 | " \"contentVersion\" = \"1.0.0.0\"\n",
218 | " \"parameters\" = @{\n",
219 | " \"apicResourceNamePrefix\" = @{ \"value\" = $apicResourceNamePrefix }\n",
220 | " \"apicResourceTags\" = @{ \"value\" = $apicResourceTags }\n",
221 | " \"apicMetadataSchema\" = @{ \"value\" = $metadata }\n",
222 | " \"apicEnvironments\" = @{ \"value\" = $environments }\n",
223 | " }\n",
224 | "}\n",
225 | "\n",
226 | "$bicepParametersJson = ConvertTo-Json -InputObject $bicepParameters -Depth 10\n",
227 | "Set-Content -Path \"params.json\" -Value $bicepParametersJson\n",
228 | "\n",
229 | "# Execute the Azure CLI command to create the deployment\n",
230 | "az deployment group create --name $deploymentName --resource-group $resourceGroupName --template-file \"main.bicep\" --parameters \"params.json\"\n",
231 | "\n"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "### 3️⃣ Get the deployment outputs\n",
239 | "\n",
240 | "We will set the `apicResourceName` variable with the value that was returned from the deployment "
241 | ]
242 | },
243 | {
244 | "cell_type": "code",
245 | "execution_count": null,
246 | "metadata": {
247 | "dotnet_interactive": {
248 | "language": "pwsh"
249 | },
250 | "polyglot_notebook": {
251 | "kernelName": "pwsh"
252 | },
253 | "vscode": {
254 | "languageId": "polyglot-notebook"
255 | }
256 | },
257 | "outputs": [],
258 | "source": [
259 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apicResourceName.value -o json\n",
260 | "if ($LASTEXITCODE -ne 0) {\n",
261 | " Write-Output $deploymentOutput\n",
262 | "} else {\n",
263 | " $apicResourceName = $deploymentOutput | ConvertFrom-Json\n",
264 | "}\n",
265 | "Write-Output \"👉🏻 API Center name: $apicResourceName\""
266 | ]
267 | },
268 | {
269 | "cell_type": "markdown",
270 | "metadata": {},
271 | "source": [
272 | "### 4️⃣ Export the APIs from AWS API Gateway and Register in API Center\n",
273 | "\n",
274 | "We will start to list all the REST APIs, then for each API we will export the OpenAPI spec, update the metadata and then create deployments for each environment.\n",
275 | "\n",
276 | "Note: this script supports REST APIs. For HTTP APIs you should adapt the script to use the [equivalent commands](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigatewayv2/index.html)."
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": null,
282 | "metadata": {
283 | "dotnet_interactive": {
284 | "language": "pwsh"
285 | },
286 | "polyglot_notebook": {
287 | "kernelName": "pwsh"
288 | },
289 | "vscode": {
290 | "languageId": "polyglot-notebook"
291 | }
292 | },
293 | "outputs": [],
294 | "source": [
295 | "\n",
296 | "# comment one of the following lines to use the real AWS API Gateway or the local file\n",
297 | "#$restAPIsJson = aws apigateway get-rest-apis --output json\n",
298 | "$restAPIsJson = Get-Content -Raw 'get-rest-apis.json'\n",
299 | "\n",
300 | "$restAPIs = $restAPIsJson | ConvertFrom-Json\n",
301 | "foreach ($restAPI in $restAPIs.items) {\n",
302 | " $restAPIId = $restAPI.name\n",
303 | "\n",
304 | " # comment one of the following lines to use the real AWS API Gateway or the local file\n",
305 | " #$restAPIJson = aws apigateway get-rest-api --rest-api-id $restAPIId --output json\n",
306 | " $restAPIJson = Get-Content -Raw 'get-rest-api.json' \n",
307 | "\n",
308 | " $restAPI = $restAPIJson | ConvertFrom-Json\n",
309 | "\n",
310 | " # uncomment the following line to export from AWS API Gateway instead of using the local file\n",
311 | " # aws apigateway get-export --rest-api-id 2q3nwrw1r0 --stage-name production --export-type oas30 $restAPIId.json\n",
312 | "\n",
313 | " write-output \"👉🏻 Registering API $restAPIId\"\n",
314 | " az apic api register -g $resourceGroupName -n $apicResourceName -l $restAPIId\".json\"\n",
315 | "\n",
316 | " $apiCustomProperties = @{ \n",
317 | " \"createdDate\" = $restAPI.createdDate \n",
318 | " \"rootResourceId\" = $restAPI.rootResourceId\n",
319 | " \"department\" = $restAPI.tags.department\n",
320 | " \"dataClassification\" = $restAPI.tags.dataClassification\n",
321 | " }\n",
322 | " $apiCustomPropertiesJson = ConvertTo-Json -InputObject $apiCustomProperties -Depth 10 -Compress\n",
323 | " write-output \"👉🏻 Updating API $restAPIId metadata\"\n",
324 | " az apic api update -g $resourceGroupName -n $apicResourceName --api-id $restAPIId --custom-properties $apiCustomPropertiesJson.replace('\"','\\\"') \n",
325 | "\n",
326 | " $openAPIJson = Get-Content -Raw $restAPIId\".json\"\n",
327 | " $openAPI = $openAPIJson | ConvertFrom-Json\n",
328 | " $version = $openAPI.info.version\n",
329 | " $runtimeUri = $openAPI.servers[0].url\n",
330 | "\n",
331 | " foreach ($environment in $environments) {\n",
332 | " $environmentName = $environment.title\n",
333 | "\n",
334 | " # comment one of the following lines to use the real AWS API Gateway or the local file\n",
335 | " # $stageJson = aws apigateway get-stage --stage-name $environmentName --rest-api-id $restAPIId\n",
336 | " $stageJson = Get-Content -Raw 'get-stage.json'\n",
337 | " \n",
338 | " $stage = $stageJson | ConvertFrom-Json\n",
339 | " $deploymentId = $stage.deploymentId\n",
340 | " $deploymentDescription = $stage.description\n",
341 | " $server = $('{\\\"runtimeUri\\\":[\\\"' + $runtimeUri.replace('{basePath}', $environmentName) + '\\\"]}')\n",
342 | "\n",
343 | " $deploymentCustomProperties = @{\n",
344 | " \"createdDate\" = $stage.createdDate\n",
345 | " }\n",
346 | " $deploymentCustomPropertiesJson = ConvertTo-Json -InputObject $deploymentCustomProperties -Depth 10 -Compress\n",
347 | " write-output \"👉🏻 Creating $environmentName deployment for API $restAPIId\"\n",
348 | " az apic api deployment create -g $resourceGroupName -n $apicResourceName --deployment-id $environmentName\"-\"$deploymentId `\n",
349 | " --title $deploymentId --description $deploymentDescription --api-id $restAPIId `\n",
350 | " --environment-id \"/workspaces/default/environments/$environmentName\" `\n",
351 | " --definition-id \"/workspaces/default/apis/$restAPIId/versions/$version/definitions/openapi\" `\n",
352 | " --server $server `\n",
353 | " --custom-properties $deploymentCustomPropertiesJson.replace('\"','\\\"') \n",
354 | " }\n",
355 | "}"
356 | ]
357 | },
358 | {
359 | "cell_type": "markdown",
360 | "metadata": {},
361 | "source": [
362 | "### 5️⃣ Discover the APIs that were just imported\n",
363 | "\n",
364 | "You can discover the APIs with fhe following methods:\n",
365 | "- With the Azure Portal\n",
366 | "- With the [self-hosted API Center Portal](https://learn.microsoft.com/en-us/azure/api-center/enable-api-center-portal)\n",
367 | "- With the [VS Code extension](https://learn.microsoft.com/en-us/azure/api-center/use-vscode-extension-copilot) that is integrated with GitHub Copilot Chat.\n",
368 | "- With the CLI, the service REST API and more\n",
369 | "\n",
370 | "Here we will use the [list command](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-list) to display the APIs that we have just imported. \n"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": null,
376 | "metadata": {
377 | "dotnet_interactive": {
378 | "language": "pwsh"
379 | },
380 | "polyglot_notebook": {
381 | "kernelName": "pwsh"
382 | },
383 | "vscode": {
384 | "languageId": "polyglot-notebook"
385 | }
386 | },
387 | "outputs": [],
388 | "source": [
389 | "az apic api list -g $resourceGroupName -n $apicResourceName --query \"[].{Name:name, Title:title, Kind:kind, ContactEmail:contacts[0].email}\" -o table"
390 | ]
391 | },
392 | {
393 | "cell_type": "markdown",
394 | "metadata": {},
395 | "source": [
396 | "### 🗑️ Clean up resources\n",
397 | "\n",
398 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n",
399 | "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that."
400 | ]
401 | }
402 | ],
403 | "metadata": {
404 | "kernelspec": {
405 | "display_name": ".NET (C#)",
406 | "language": "C#",
407 | "name": ".net-csharp"
408 | },
409 | "language_info": {
410 | "codemirror_mode": {
411 | "name": "ipython",
412 | "version": 3
413 | },
414 | "file_extension": ".py",
415 | "mimetype": "text/x-python",
416 | "name": "python",
417 | "nbconvert_exporter": "python",
418 | "pygments_lexer": "ipython3",
419 | "version": "3.11.9"
420 | },
421 | "polyglot_notebook": {
422 | "kernelInfo": {
423 | "defaultKernelName": "csharp",
424 | "items": [
425 | {
426 | "aliases": [],
427 | "name": "csharp"
428 | }
429 | ]
430 | }
431 | }
432 | },
433 | "nbformat": 4,
434 | "nbformat_minor": 2
435 | }
436 |
--------------------------------------------------------------------------------
/labs/import-from-aws/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-azure-apim/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Azure API Management
4 | 
5 |
6 | Playground to experiment importing APIs from Azure APIM into API Center. We start by creating APIM and API Center instances using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Azure CLI]((https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest)) to import the APIs from APIM.
7 |
8 | ### Prerequisites
9 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
10 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
11 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
12 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
13 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
14 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
15 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
16 |
17 | ### 🚀 Get started
18 | Proceed by opening the [Jupyter notebook](import-from-azure-apim.ipynb), and follow the steps provided.
19 |
20 | ### 🗑️ Clean up resources
21 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
22 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-azure-apim/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": 1,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [
27 | {
28 | "name": "stdout",
29 | "output_type": "stream",
30 | "text": [
31 | "✅ Resource group lab-import-from-azure-apim deleted ⌚ 00:29:58\r\n"
32 | ]
33 | }
34 | ],
35 | "source": [
36 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
37 | "$resourceGroupName = \"lab-$deploymentName\"\n",
38 | "\n",
39 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
40 | "if ($LASTEXITCODE -ne 0) {\n",
41 | " Write-Output $deleteOutput\n",
42 | "} else {\n",
43 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
44 | "}\n"
45 | ]
46 | }
47 | ],
48 | "metadata": {
49 | "kernelspec": {
50 | "display_name": "Python 3",
51 | "language": "python",
52 | "name": "python3"
53 | },
54 | "language_info": {
55 | "codemirror_mode": {
56 | "name": "ipython",
57 | "version": 3
58 | },
59 | "file_extension": ".py",
60 | "mimetype": "text/x-python",
61 | "name": "python",
62 | "nbconvert_exporter": "python",
63 | "pygments_lexer": "ipython3",
64 | "version": "3.11.9"
65 | }
66 | },
67 | "nbformat": 4,
68 | "nbformat_minor": 2
69 | }
70 |
--------------------------------------------------------------------------------
/labs/import-from-azure-apim/import-from-azure-apim.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# API Center ❤️ all APIs\n",
8 | "\n",
9 | "## Import from Azure API Management\n",
10 | "\n",
11 | "\n",
12 | "Playground to experiment importing APIs from Azure APIM into API Center. We start by creating APIM and API Center instances using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Azure CLI]((https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest)) to import the APIs from APIM.\n",
13 | "\n",
14 | "▶️ Set the kernel to `.NET Interactive` before running the PowerShell scripts.\n",
15 | "\n",
16 | "💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.\n",
17 | "\n",
18 | "### Learning Objectives - Upon completing this lab, you should be able to:\n",
19 | "- Deploy Azure API Management and Azure API Center using Bicep. With a role assignment allowing API Center to read APIs from APIM.\n",
20 | "- Deploy sample APIs in APIM.\n",
21 | "- Configure the API Center metadata scheme for APIs, Environments and Deployments.\n",
22 | "- Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).\n",
23 | "- Execute the [import-from-apim](https://learn.microsoft.com/en-us/cli/azure/apic/service?view=azure-cli-latest#az-apic-service-import-from-apim) command.\n",
24 | "- List the APIs imported.\n",
25 | "\n",
26 | "### Prerequisites\n",
27 | "- Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)\n",
28 | "- Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)\n",
29 | "- Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace\n",
30 | "- Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)\n",
31 | "- Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.\n",
32 | "- [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions\n",
33 | "- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)\n",
34 | "- [Register the Microsoft.ApiCenter provider](https://learn.microsoft.com/en-us/azure/api-center/set-up-api-center-azure-cli#register-the-microsoftapicenter-provider)\n",
35 | "\n",
36 | "The [Oficial documentation](https://learn.microsoft.com/en-us/azure/api-center/import-api-management-apis?tabs=portal) describes in detail the process."
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "### 0️⃣ Initialize notebook variables\n",
44 | "\n",
45 | "- Resources will be suffixed by a unique string based on your subscription id\n",
46 | "- Adjust the APIC location parameter according your preferences and [region availability.](https://learn.microsoft.com/en-us/azure/api-center/overview#available-regions) \n"
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {
53 | "dotnet_interactive": {
54 | "language": "pwsh"
55 | },
56 | "polyglot_notebook": {
57 | "kernelName": "pwsh"
58 | },
59 | "vscode": {
60 | "languageId": "polyglot-notebook"
61 | }
62 | },
63 | "outputs": [],
64 | "source": [
65 | "\n",
66 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
67 | "$resourceGroupName = \"lab-$deploymentName\" # change the name to match your naming style\n",
68 | "$resourceGroupLocation = \"westeurope\"\n",
69 | "$apicResourceNamePrefix = \"apic\"\n",
70 | "$apicResourceSku = \"free\"\n",
71 | "$apicResourceTags = @{\n",
72 | " \"lab\" = $deploymentName\n",
73 | "}\n",
74 | "$apimResourceNamePrefix = \"apim\"\n",
75 | "$apimResourceLocation = \"westeurope\"\n",
76 | "$apimResourceSku = \"Basicv2\"\n",
77 | "\n",
78 | "# the following metadata will be created during the deployment\n",
79 | "$metadata = @(\n",
80 | " @{\n",
81 | " \"name\" = 'termsOfService'\n",
82 | " \"schema\" = '{\"title\":\"termsOfService\",\"description\":\"The terms of service URL for using the API\",\"type\":\"string\",\"format\":\"uri\"}'\n",
83 | " \"assignedTo\" = @(\n",
84 | " @{\n",
85 | " \"entity\" = 'api'\n",
86 | " \"required\" = $false\n",
87 | " }\n",
88 | " )\n",
89 | " },\n",
90 | " @{\n",
91 | " \"name\" = 'externalDocs'\n",
92 | " \"schema\" = '{\"title\":\"externalDocs\",\"description\":\"External Documents that describe the API\",\"type\":\"object\",\"properties\":{\"description\":{\"title\":\"description\",\"description\":\"Description of the External Documents\",\"type\":\"string\"},\"url\":{\"title\":\"url\",\"description\":\"The URL to reference the external documents\",\"type\":\"string\",\"format\":\"uri\"}},\"required\":[\"url\"]}'\n",
93 | " \"assignedTo\" = @(\n",
94 | " @{\n",
95 | " \"entity\" = 'api'\n",
96 | " \"required\" = $false\n",
97 | " }\n",
98 | " )\n",
99 | " },\n",
100 | " @{\n",
101 | " \"name\" = 'sourceControl'\n",
102 | " \"schema\" = '{\"title\":\"sourceControl\",\"description\":\"Source Control Info\",\"type\":\"object\",\"properties\":{\"type\":{\"type\":\"string\",\"title\":\"type\",\"description\":\"Source Control System type\",\"oneOf\":[{\"const\":\"GitHub\",\"description\":\"\"},{\"const\":\"GitLab\",\"description\":\"\"},{\"const\":\"Bitbucket\",\"description\":\"\"},{\"const\":\"Other\",\"description\":\"\"}]},\"repository\":{\"title\":\"repository\",\"description\":\"URL for the repository\",\"type\":\"string\",\"format\":\"uri\"},\"url\":{\"title\":\"url\",\"description\":\"Full URL for the API definition stored in the source control system\",\"type\":\"string\",\"format\":\"uri\"}},\"required\":[\"type\",\"repository\",\"url\"]}'\n",
103 | " \"assignedTo\" = @(\n",
104 | " @{\n",
105 | " \"entity\" = 'api'\n",
106 | " \"required\" = $false\n",
107 | " }\n",
108 | " )\n",
109 | " },\n",
110 | " @{\n",
111 | " \"name\" = 'securitySchemes'\n",
112 | " \"schema\" = '{\"title\":\"securitySchemes\",\"description\":\"API Security Schemes\",\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"name\":{\"title\":\"name\",\"description\":\"Name of the API Security Scheme\",\"type\":\"string\"},\"type\":{\"type\":\"string\",\"title\":\"type\",\"description\":\"The Type of the API Security Scheme\",\"oneOf\":[{\"const\":\"http\",\"description\":\"Basic, Bearer and other HTTP authentications schemes\"},{\"const\":\"apiKey\",\"description\":\"API keys and cookie authentication\"},{\"const\":\"oauth2\",\"description\":\"OAuth 2.0 is the industry-standard protocol for authorization.\"},{\"const\":\"openIdConnect \",\"description\":\"OpenID Connect Discovery\"}]},\"authorizationurl\":{\"title\":\"authorizationUrl\",\"type\":\"string\",\"format\":\"uri\"}},\"required\":[\"name\",\"type\"]}}'\n",
113 | " \"assignedTo\" = @(\n",
114 | " @{\n",
115 | " \"entity\" = 'deployment'\n",
116 | " \"required\" = $false\n",
117 | " }\n",
118 | " )\n",
119 | " },\n",
120 | " @{\n",
121 | " \"name\" = 'host'\n",
122 | " \"schema\" = '{\"title\":\"host\",\"description\":\"The name of the host that is hosting the API\",\"type\":\"string\"}'\n",
123 | " \"assignedTo\" = @(\n",
124 | " @{\n",
125 | " \"entity\" = 'environment'\n",
126 | " \"required\" = $false\n",
127 | " }\n",
128 | " )\n",
129 | " }\n",
130 | ")\n",
131 | "\n",
132 | "# the following environment(s) will be created during the deployment\n",
133 | "$environments = @(\n",
134 | " @{\n",
135 | " \"title\" = 'prod'\n",
136 | " \"kind\" = 'production'\n",
137 | " \"description\" = 'Production Environment'\n",
138 | " \"server\" = @{\n",
139 | " \"type\" = 'Kubernetes' \n",
140 | " \"managementPortalUri\" = 'https://swagger.io/tools/swaggerhub/'\n",
141 | " }\n",
142 | " \"onboarding\" = @{\n",
143 | " \"developerPortalUri\" = 'https://swagger.io/tools/swaggerhub/features/swaggerhub-portal/'\n",
144 | " \"instructions\" = 'Sign in and access the developer portal to get started with the API'\n",
145 | " }\n",
146 | " \"customProperties\" = @{ \n",
147 | " }\n",
148 | " }\n",
149 | ")\n",
150 | "\n",
151 | "$environmentCustomProperties = @{\n",
152 | " \"host\" = \"petstore3.swagger.io\"\n",
153 | "}\n",
154 | "\n",
155 | "$apiCustomProperties = @{\n",
156 | " \"termsOfService\" = \"http://swagger.io/terms/\"\n",
157 | " \"externalDocs\" = @{\n",
158 | " \"description\" = \"Find out more about Swagger\"\n",
159 | " \"url\" = \"http://swagger.io\"\n",
160 | " }\n",
161 | " \"sourceControl\" = @{\n",
162 | " \"type\" = \"GitHub\"\n",
163 | " \"repository\" = \"https://github.com/swagger-api/swagger-petstore\"\n",
164 | " \"url\" = \"https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml\"\n",
165 | " }\n",
166 | "}\n",
167 | "\n",
168 | "$deploymentCustomProperties = @{\n",
169 | " \"securitySchemes\" = @(\n",
170 | " @{\n",
171 | " \"name\" = \"petstore_auth\"\n",
172 | " \"type\" = \"oauth2\"\n",
173 | " \"authorizationurl\" = \"https://petstore3.swagger.io/oauth/authorize\"\n",
174 | " }\n",
175 | " )\n",
176 | "}\n",
177 | "\n",
178 | "$apisConfig = @(\n",
179 | " @{\n",
180 | " \"name\" = 'petstore'\n",
181 | " \"type\" = 'http'\n",
182 | " \"revision\" = '1-0-20-SNAPSHOT'\n",
183 | " \"revisionDescription\" = '1.0.20-SNAPSHOT'\n",
184 | " \"displayName\" = 'Petstore'\n",
185 | " \"description\" = 'Sample Pet Store Server'\n",
186 | " 'contact' = @{\n",
187 | " 'name' = 'API Team'\n",
188 | " 'email' = 'apiteam@swagger.io'\n",
189 | " 'url' = 'http://swagger.io'\n",
190 | " }\n",
191 | " 'license' = @{\n",
192 | " 'name' = 'Apache 2.0'\n",
193 | " 'url' = 'http://www.apache.org/licenses/LICENSE-2.0.html'\n",
194 | " }\n",
195 | " 'format' = 'openapi-link'\n",
196 | " \"path\" = 'petstore'\n",
197 | " 'termsOfServiceUrl' = 'http://swagger.io/terms/'\n",
198 | " \"serviceUrl\" = 'https://petstore3.swagger.io/api/v3'\n",
199 | " \"specURL\" = 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml'\n",
200 | " },\n",
201 | " @{\n",
202 | " \"name\" = 'openai'\n",
203 | " \"type\" = 'http'\n",
204 | " \"revision\" = '2024-02-01'\n",
205 | " \"revisionDescription\" = '2024-02-01'\n",
206 | " \"displayName\" = 'OpenAI'\n",
207 | " \"description\" = 'OpenAI inference API'\n",
208 | " 'contact' = @{\n",
209 | " 'name' = 'OpenAI Team'\n",
210 | " 'email' = 'openai@microsoft.com'\n",
211 | " 'url' = 'http://www.microsoft.com'\n",
212 | " }\n",
213 | " 'license' = @{\n",
214 | " 'name' = 'MIT License'\n",
215 | " 'url' = 'Http://opensource.org/licenses/MIT'\n",
216 | " }\n",
217 | " 'format' = 'openapi-link'\n",
218 | " \"path\" = 'openai'\n",
219 | " 'termsOfServiceUrl' = 'https://learn.microsoft.com/en-us/legal/cognitive-services/openai/code-of-conduct'\n",
220 | " \"serviceUrl\" = 'https://your-resource-name.openai.azure.com'\n",
221 | " \"specURL\" = 'https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/stable/2024-02-01/inference.json'\n",
222 | " }\n",
223 | ")\n",
224 | "\n",
225 | "Write-Output \"✅ Variables initialized ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n"
226 | ]
227 | },
228 | {
229 | "cell_type": "markdown",
230 | "metadata": {},
231 | "source": [
232 | "### 1️⃣ Create the Azure Resource Group\n",
233 | "All resources deployed in this lab will be created in the specified resource group. Skip this step if you want to use an existing resource group."
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": null,
239 | "metadata": {
240 | "dotnet_interactive": {
241 | "language": "pwsh"
242 | },
243 | "polyglot_notebook": {
244 | "kernelName": "pwsh"
245 | },
246 | "vscode": {
247 | "languageId": "polyglot-notebook"
248 | }
249 | },
250 | "outputs": [],
251 | "source": [
252 | "$resourceGroupOutput = az group create --name $resourceGroupName --location $resourceGroupLocation\n",
253 | "\n",
254 | "if ($LASTEXITCODE -ne 0) {\n",
255 | " Write-Output $resourceGroupOutput\n",
256 | "} else {\n",
257 | " Write-Output \"✅ Azure Resource Grpup $resourceGroupName created ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
258 | "}"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "metadata": {},
264 | "source": [
265 | "### 2️⃣ Create deployment using 🦾 Bicep\n",
266 | "\n",
267 | "This lab uses [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declarative define all the resources that will be deployed. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations. "
268 | ]
269 | },
270 | {
271 | "cell_type": "code",
272 | "execution_count": null,
273 | "metadata": {
274 | "dotnet_interactive": {
275 | "language": "pwsh"
276 | },
277 | "polyglot_notebook": {
278 | "kernelName": "pwsh"
279 | },
280 | "vscode": {
281 | "languageId": "polyglot-notebook"
282 | }
283 | },
284 | "outputs": [],
285 | "source": [
286 | "$bicepParameters = @{\n",
287 | " \"`$schema\" = \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\"\n",
288 | " \"contentVersion\" = \"1.0.0.0\"\n",
289 | " \"parameters\" = @{\n",
290 | " \"apicResourceNamePrefix\" = @{ \"value\" = $apicResourceNamePrefix }\n",
291 | " \"apicResourceTags\" = @{ \"value\" = $apicResourceTags }\n",
292 | " \"apicMetadataSchema\" = @{ \"value\" = $metadata }\n",
293 | " \"apicEnvironments\" = @{ \"value\" = $environments }\n",
294 | " \"apimResourceNamePrefix\" = @{ \"value\" = $apimResourceNamePrefix }\n",
295 | " \"apimResourceLocation\" = @{ \"value\" = $apimResourceLocation }\n",
296 | " \"apimResourceSku\" = @{ \"value\" = $apimResourceSku }\n",
297 | " \"apisConfig\" = @{ \"value\" = $apisConfig }\n",
298 | " }\n",
299 | "}\n",
300 | "\n",
301 | "$bicepParametersJson = ConvertTo-Json -InputObject $bicepParameters -Depth 10\n",
302 | "Set-Content -Path \"params.json\" -Value $bicepParametersJson\n",
303 | "\n",
304 | "# Execute the Azure CLI command to create the deployment\n",
305 | "az deployment group create --name $deploymentName --resource-group $resourceGroupName --template-file \"main.bicep\" --parameters \"params.json\"\n",
306 | "\n"
307 | ]
308 | },
309 | {
310 | "cell_type": "markdown",
311 | "metadata": {},
312 | "source": [
313 | "### 3️⃣ Get the deployment outputs\n",
314 | "\n",
315 | "We will set the `apicResourceName` variable with the value that was returned from the deployment "
316 | ]
317 | },
318 | {
319 | "cell_type": "code",
320 | "execution_count": null,
321 | "metadata": {
322 | "dotnet_interactive": {
323 | "language": "pwsh"
324 | },
325 | "polyglot_notebook": {
326 | "kernelName": "pwsh"
327 | },
328 | "vscode": {
329 | "languageId": "polyglot-notebook"
330 | }
331 | },
332 | "outputs": [],
333 | "source": [
334 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apicResourceName.value -o json\n",
335 | "if ($LASTEXITCODE -ne 0) {\n",
336 | " Write-Output $deploymentOutput\n",
337 | "} else {\n",
338 | " $apicResourceName = $deploymentOutput | ConvertFrom-Json\n",
339 | "}\n",
340 | "Write-Output \"👉🏻 API Center name: $apicResourceName\"\n",
341 | "\n",
342 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apimResourceId.value -o json\n",
343 | "if ($LASTEXITCODE -ne 0) {\n",
344 | " Write-Output $deploymentOutput\n",
345 | "} else {\n",
346 | " $apimResourceId = $deploymentOutput | ConvertFrom-Json\n",
347 | "}\n",
348 | "Write-Output \"👉🏻 API Management id: $apimResourceId\""
349 | ]
350 | },
351 | {
352 | "cell_type": "markdown",
353 | "metadata": {},
354 | "source": [
355 | "### 4️⃣ Update the environment metadata\n",
356 | "\n",
357 | "We will [update the enviroment](https://learn.microsoft.com/en-us/cli/azure/apic/environment?view=azure-cli-latest#az-apic-environment-update) with the `custom properties` defined in the variable `environmentCustomProperties`"
358 | ]
359 | },
360 | {
361 | "cell_type": "code",
362 | "execution_count": null,
363 | "metadata": {
364 | "dotnet_interactive": {
365 | "language": "pwsh"
366 | },
367 | "polyglot_notebook": {
368 | "kernelName": "pwsh"
369 | },
370 | "vscode": {
371 | "languageId": "polyglot-notebook"
372 | }
373 | },
374 | "outputs": [],
375 | "source": [
376 | "$environmentCustomPropertiesJson = ConvertTo-Json -InputObject $environmentCustomProperties -Depth 10 -Compress\n",
377 | "az apic environment update -g $resourceGroupName -s $apicResourceName --environment-id \"prod\" `\n",
378 | " --custom-properties $environmentCustomPropertiesJson.replace('\"','\\\"')"
379 | ]
380 | },
381 | {
382 | "cell_type": "markdown",
383 | "metadata": {},
384 | "source": [
385 | "### 5️⃣ Import the Azure API Management APIs into Azure API Center\n",
386 | "\n",
387 | "We will use the [import-from-apim](https://learn.microsoft.com/en-us/cli/azure/apic/service?view=azure-cli-latest#az-apic-service-import-from-apim) command with the wildcard to import all the APIs."
388 | ]
389 | },
390 | {
391 | "cell_type": "code",
392 | "execution_count": null,
393 | "metadata": {
394 | "dotnet_interactive": {
395 | "language": "pwsh"
396 | },
397 | "polyglot_notebook": {
398 | "kernelName": "pwsh"
399 | },
400 | "vscode": {
401 | "languageId": "polyglot-notebook"
402 | }
403 | },
404 | "outputs": [],
405 | "source": [
406 | "az apic service import-from-apim -g $resourceGroupName -s $apicResourceName --source-resource-ids \"$apimResourceId/apis/*\""
407 | ]
408 | },
409 | {
410 | "cell_type": "markdown",
411 | "metadata": {},
412 | "source": [
413 | "### 6️⃣ Discover the APIs that were just imported\n",
414 | "\n",
415 | "You can discover the APIs with fhe following methods:\n",
416 | "- With the Azure Portal\n",
417 | "- With the [self-hosted API Center Portal](https://learn.microsoft.com/en-us/azure/api-center/enable-api-center-portal)\n",
418 | "- With the [VS Code extension](https://learn.microsoft.com/en-us/azure/api-center/use-vscode-extension-copilot) that is integrated with GitHub Copilot Chat.\n",
419 | "- With the CLI, the service REST API and more\n",
420 | "\n",
421 | "Here we will use the [list command](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-list) to display the APIs that we have just imported. \n"
422 | ]
423 | },
424 | {
425 | "cell_type": "code",
426 | "execution_count": null,
427 | "metadata": {
428 | "dotnet_interactive": {
429 | "language": "pwsh"
430 | },
431 | "polyglot_notebook": {
432 | "kernelName": "pwsh"
433 | },
434 | "vscode": {
435 | "languageId": "polyglot-notebook"
436 | }
437 | },
438 | "outputs": [],
439 | "source": [
440 | "az apic api list -g $resourceGroupName -s $apicResourceName --query \"[].{Name:name, Title:title, Kind:kind, ContantEmail:contacts[0].email}\" -o table"
441 | ]
442 | },
443 | {
444 | "cell_type": "markdown",
445 | "metadata": {},
446 | "source": [
447 | "### 🗑️ Clean up resources\n",
448 | "\n",
449 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n",
450 | "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that."
451 | ]
452 | }
453 | ],
454 | "metadata": {
455 | "kernelspec": {
456 | "display_name": "Python 3",
457 | "language": "python",
458 | "name": "python3"
459 | },
460 | "language_info": {
461 | "codemirror_mode": {
462 | "name": "ipython",
463 | "version": 3
464 | },
465 | "file_extension": ".py",
466 | "mimetype": "text/x-python",
467 | "name": "python",
468 | "nbconvert_exporter": "python",
469 | "pygments_lexer": "ipython3",
470 | "version": "3.11.9"
471 | }
472 | },
473 | "nbformat": 4,
474 | "nbformat_minor": 2
475 | }
476 |
--------------------------------------------------------------------------------
/labs/import-from-azure-apim/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 | @description('The prefix name of the API Management resource')
18 | param apimResourceNamePrefix string
19 |
20 | @description('Location for the APIM resource')
21 | param apimResourceLocation string = resourceGroup().location
22 |
23 | @description('The pricing tier of this API Management service')
24 | @allowed([
25 | 'Consumption'
26 | 'Developer'
27 | 'Basic'
28 | 'Basicv2'
29 | 'Standard'
30 | 'Standardv2'
31 | 'Premium'
32 | ])
33 | param apimResourceSku string = 'Consumption'
34 |
35 | @description('The instance size of this API Management service.')
36 | @allowed([
37 | 0
38 | 1
39 | 2
40 | ])
41 | param apimResourceSkuCount int = 1
42 |
43 | @description('The email address of the owner of the service')
44 | param apimPublisherEmail string = 'noreply@microsoft.com'
45 |
46 | @description('The name of the owner of the service')
47 | param apimPublisherName string = 'Microsoft'
48 |
49 | @description('List of API resources to create.')
50 | param apisConfig array = []
51 |
52 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
53 |
54 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
55 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
56 | location: apicResourceLocation
57 | tags: apicResourceTags
58 | identity: {
59 | type: 'SystemAssigned'
60 | }
61 | }
62 |
63 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
64 | name: metadata.name
65 | parent: apic
66 | properties: {
67 | schema: metadata.schema
68 | assignedTo: [for assignedTo in metadata.assignedTo: {
69 | deprecated: false
70 | entity: assignedTo.entity
71 | required: assignedTo.required
72 | }
73 | ]
74 | }
75 | }]
76 |
77 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
78 | name: 'default'
79 | parent: apic
80 | }
81 |
82 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
83 | name: environment.title
84 | parent: apicWorkspace
85 | properties: {
86 | customProperties: environment.customProperties
87 | description: environment.description
88 | kind: environment.kind
89 | onboarding: {
90 | developerPortalUri: [
91 | environment.onboarding.developerPortalUri
92 | ]
93 | instructions: environment.onboarding.instructions
94 | }
95 | server: {
96 | managementPortalUri: [
97 | environment.server.managementPortalUri
98 | ]
99 | type: environment.server.type
100 | }
101 | title: environment.title
102 | }
103 | }]
104 |
105 | resource apimService 'Microsoft.ApiManagement/service@2023-05-01-preview' = {
106 | name: '${apimResourceNamePrefix}-${resourceSuffix}'
107 | location: apimResourceLocation
108 | sku: {
109 | name: apimResourceSku
110 | capacity: (apimResourceSku == 'Consumption') ? 0 : ((apimResourceSku == 'Developer') ? 1 : apimResourceSkuCount)
111 | }
112 | properties: {
113 | publisherEmail: apimPublisherEmail
114 | publisherName: apimPublisherName
115 | }
116 | identity: {
117 | type: 'SystemAssigned'
118 | }
119 | }
120 |
121 | var roleDefinitionID = resourceId('Microsoft.Authorization/roleDefinitions', '71522526-b88f-4d52-b57f-d31fc3546d0d') // API Management Service Reader Role
122 | resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
123 | scope: apimService
124 | name: guid(subscription().id, resourceGroup().id, apimService.name, roleDefinitionID)
125 | properties: {
126 | roleDefinitionId: roleDefinitionID
127 | principalId: apic.identity.principalId
128 | principalType: 'ServicePrincipal'
129 | }
130 | }
131 |
132 | resource apiResource 'Microsoft.ApiManagement/service/apis@2023-05-01-preview' = [for (api, i) in apisConfig: if(length(apisConfig) > 0) {
133 | name: api.name
134 | parent: apimService
135 | properties: {
136 | apiRevision: api.revision
137 | apiRevisionDescription: api.revisionDescription
138 | apiType: api.type
139 | description: api.description
140 | displayName: api.displayName
141 | contact: {
142 | email: api.contact.email
143 | name: api.contact.name
144 | url: api.contact.url
145 | }
146 | license: {
147 | name: api.license.name
148 | url: api.license.url
149 | }
150 | format: api.format
151 | path: api.path
152 | serviceUrl: api.serviceUrl
153 | protocols: [
154 | 'https'
155 | ]
156 | subscriptionKeyParameterNames: {
157 | header: 'api-key'
158 | query: 'api-key'
159 | }
160 | subscriptionRequired: true
161 | termsOfServiceUrl: api.termsOfServiceUrl
162 | type: api.type
163 | value: api.specURL
164 | }
165 | }]
166 |
167 |
168 | output apicResourceId string = apic.id
169 | output apicResourceName string = apic.name
170 | output apicResourcePrincipalId string = apic.identity.principalId
171 |
172 | output apimResourceId string = apimService.id
173 | output apimResourceName string = apimService.name
174 |
--------------------------------------------------------------------------------
/labs/import-from-gcp/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Apigee API Management
4 | 
5 |
6 | Playground to experiment importing APIs from Apigee. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [GCP CLI](https://cloud.google.com/sdk/docs/install-sdk) to export the Apigee APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Learning Objectives - Upon completing this lab, you should be able to:
11 | - Deploy Azure API Center using Bicep.
12 | - Import environments from Apigee
13 | - Import APIs from Apigee
14 | - Import API deployments from Apigee
15 | - Search and discover the APIs registered in API Center.
16 |
17 | ### Prerequisites
18 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
19 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
20 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
21 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
22 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
23 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
24 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
25 | - Install or update to the latest [GCP CLI](https://cloud.google.com/sdk/docs/install-sdk) and set your Apigee project
26 |
--------------------------------------------------------------------------------
/labs/import-from-gcp/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-gcp/import-from-gcp.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# API Center ❤️ all APIs\n",
8 | "\n",
9 | "## Import from Apigee API Management\n",
10 | "\n",
11 | "\n",
12 | "Playground to experiment importing APIs from Apigee. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [GCP CLI](https://cloud.google.com/sdk/docs/install-sdk) to export the Apigee APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center.\n",
13 | "\n",
14 | "💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.\n",
15 | "\n",
16 | "### Learning Objectives - Upon completing this lab, you should be able to:\n",
17 | "- Deploy Azure API Center using Bicep.\n",
18 | "- Import environments from Apigee\n",
19 | "- Import APIs from Apigee\n",
20 | "- Import API deployments from Apigee\n",
21 | "- Search and discover the APIs registered in API Center.\n",
22 | "\n",
23 | "### Prerequisites\n",
24 | "- Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)\n",
25 | "- Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)\n",
26 | "- Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace\n",
27 | "- Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)\n",
28 | "- Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.\n",
29 | "- [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions\n",
30 | "- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)\n",
31 | "- Install or update to the latest [GCP CLI](https://cloud.google.com/sdk/docs/install-sdk) and set your Apigee project\n"
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {},
37 | "source": [
38 | "### 0️⃣ Initialize notebook variables\n",
39 | "\n",
40 | "- Resources will be suffixed by a unique string based on your subscription id\n",
41 | "- Adjust the APIC location parameter according your preferences and [region availability.](https://learn.microsoft.com/en-us/azure/api-center/overview#available-regions) \n"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {
48 | "dotnet_interactive": {
49 | "language": "pwsh"
50 | },
51 | "polyglot_notebook": {
52 | "kernelName": "pwsh"
53 | },
54 | "vscode": {
55 | "languageId": "polyglot-notebook"
56 | }
57 | },
58 | "outputs": [],
59 | "source": [
60 | "\n",
61 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
62 | "$resourceGroupName = \"lab-$deploymentName\" # change the name to match your naming style\n",
63 | "$resourceGroupLocation = \"westeurope\"\n",
64 | "$apicResourceNamePrefix = \"apic\"\n",
65 | "$apicResourceSku = \"free\"\n",
66 | "$apicResourceTags = @{\n",
67 | " \"lab\" = $deploymentName\n",
68 | "}\n",
69 | "\n",
70 | "# the following metadata will be created during the Bicep deployment\n",
71 | "$metadata = @(\n",
72 | " @{\n",
73 | " \"name\" = 'createdAt'\n",
74 | " \"schema\" = '{\"title\":\"createdAt\",\"description\":\"When the API was created in Apigee\",\"type\":\"string\"}'\n",
75 | " \"assignedTo\" = @(\n",
76 | " @{\n",
77 | " \"entity\" = 'api'\n",
78 | " \"required\" = $false\n",
79 | " }\n",
80 | " )\n",
81 | " },\n",
82 | " @{\n",
83 | " \"name\" = 'deployStartTime'\n",
84 | " \"schema\" = '{\"title\":\"deployStartTime\",\"description\":\"When the API was deployed in Apigee\",\"type\":\"string\"}'\n",
85 | " \"assignedTo\" = @(\n",
86 | " @{\n",
87 | " \"entity\" = 'deployment'\n",
88 | " \"required\" = $false\n",
89 | " }\n",
90 | " )\n",
91 | " }\n",
92 | ")\n",
93 | "\n",
94 | "# the following environment(s) will be created during the deployment\n",
95 | "$environments = @(\n",
96 | ")\n",
97 | "\n",
98 | "Write-Output \"✅ Variables initialized ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n"
99 | ]
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {},
104 | "source": [
105 | "### 1️⃣ Create the Azure Resource Group\n",
106 | "All resources deployed in this lab will be created in the specified resource group. Skip this step if you want to use an existing resource group."
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "metadata": {
113 | "dotnet_interactive": {
114 | "language": "pwsh"
115 | },
116 | "polyglot_notebook": {
117 | "kernelName": "pwsh"
118 | },
119 | "vscode": {
120 | "languageId": "polyglot-notebook"
121 | }
122 | },
123 | "outputs": [],
124 | "source": [
125 | "$resourceGroupOutput = az group create --name $resourceGroupName --location $resourceGroupLocation\n",
126 | "\n",
127 | "if ($LASTEXITCODE -ne 0) {\n",
128 | " Write-Output $resourceGroupOutput\n",
129 | "} else {\n",
130 | " Write-Output \"✅ Azure Resource Grpup $resourceGroupName created ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
131 | "}"
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "metadata": {},
137 | "source": [
138 | "### 2️⃣ Create deployment using 🦾 Bicep\n",
139 | "\n",
140 | "This lab uses [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declarative define all the resources that will be deployed. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations. "
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {
147 | "dotnet_interactive": {
148 | "language": "pwsh"
149 | },
150 | "polyglot_notebook": {
151 | "kernelName": "pwsh"
152 | },
153 | "vscode": {
154 | "languageId": "polyglot-notebook"
155 | }
156 | },
157 | "outputs": [],
158 | "source": [
159 | "$bicepParameters = @{\n",
160 | " \"`$schema\" = \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\"\n",
161 | " \"contentVersion\" = \"1.0.0.0\"\n",
162 | " \"parameters\" = @{\n",
163 | " \"apicResourceNamePrefix\" = @{ \"value\" = $apicResourceNamePrefix }\n",
164 | " \"apicResourceTags\" = @{ \"value\" = $apicResourceTags }\n",
165 | " \"apicMetadataSchema\" = @{ \"value\" = $metadata }\n",
166 | " \"apicEnvironments\" = @{ \"value\" = $environments }\n",
167 | " }\n",
168 | "}\n",
169 | "\n",
170 | "$bicepParametersJson = ConvertTo-Json -InputObject $bicepParameters -Depth 10\n",
171 | "Set-Content -Path \"params.json\" -Value $bicepParametersJson\n",
172 | "\n",
173 | "# Execute the Azure CLI command to create the deployment\n",
174 | "az deployment group create --name $deploymentName --resource-group $resourceGroupName --template-file \"main.bicep\" --parameters \"params.json\"\n",
175 | "\n"
176 | ]
177 | },
178 | {
179 | "cell_type": "markdown",
180 | "metadata": {},
181 | "source": [
182 | "### 3️⃣ Get the deployment outputs\n",
183 | "\n",
184 | "We will set the `apicResourceName` variable with the value that was returned from the deployment "
185 | ]
186 | },
187 | {
188 | "cell_type": "code",
189 | "execution_count": null,
190 | "metadata": {
191 | "dotnet_interactive": {
192 | "language": "pwsh"
193 | },
194 | "polyglot_notebook": {
195 | "kernelName": "pwsh"
196 | },
197 | "vscode": {
198 | "languageId": "polyglot-notebook"
199 | }
200 | },
201 | "outputs": [],
202 | "source": [
203 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apicResourceName.value -o json\n",
204 | "if ($LASTEXITCODE -ne 0) {\n",
205 | " Write-Output $deploymentOutput\n",
206 | "} else {\n",
207 | " $apicResourceName = $deploymentOutput | ConvertFrom-Json\n",
208 | "}\n",
209 | "Write-Output \"👉🏻 API Center name: $apicResourceName\""
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "### 4️⃣ Get and import Apigee environments\n",
217 | "\n",
218 | "We will start by [getting the environments from Apigee](https://cloud.google.com/sdk/gcloud/reference/apigee) and create the environments in API Center\n"
219 | ]
220 | },
221 | {
222 | "cell_type": "code",
223 | "execution_count": null,
224 | "metadata": {
225 | "dotnet_interactive": {
226 | "language": "pwsh"
227 | },
228 | "polyglot_notebook": {
229 | "kernelName": "pwsh"
230 | },
231 | "vscode": {
232 | "languageId": "polyglot-notebook"
233 | }
234 | },
235 | "outputs": [],
236 | "source": [
237 | "\n",
238 | "$apigeeEnvironmentsJson = gcloud apigee environments list --format=json\n",
239 | "$apigeeEnvironments = $apigeeEnvironmentsJson | ConvertFrom-Json\n",
240 | "foreach ($environment in $apigeeEnvironments) {\n",
241 | " Write-Output \"👉🏻 Creating environment $environment\"\n",
242 | " az apic environment create -g $resourceGroupName -s $apicResourceName --environment-id $environment --title $environment --type \"production\" `\n",
243 | " --server '{\\\"type\\\":\\\"Apigee API Management\\\"}'\n",
244 | "}\n"
245 | ]
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {},
250 | "source": [
251 | "### 5️⃣ Import the Apigee APIs into API Center\n",
252 | "\n",
253 | "Get the APIs from Apigee and register in API Center with version and definition."
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {
260 | "dotnet_interactive": {
261 | "language": "pwsh"
262 | },
263 | "polyglot_notebook": {
264 | "kernelName": "pwsh"
265 | },
266 | "vscode": {
267 | "languageId": "polyglot-notebook"
268 | }
269 | },
270 | "outputs": [],
271 | "source": [
272 | "$apigeeAPIsJson = gcloud apigee apis list --format=json\n",
273 | "$apigeeAPIs = $apigeeAPIsJson | ConvertFrom-Json\n",
274 | "foreach ($apigeeAPI in $apigeeAPIs) {\n",
275 | " $apiJson = gcloud apigee apis describe $apigeeAPI --format=json\n",
276 | " $api = $apiJson | ConvertFrom-Json\n",
277 | "\n",
278 | " $apiCustomProperties = @{\n",
279 | " \"createdAt\" = $api.metaData.createdAt\n",
280 | " }\n",
281 | "\n",
282 | " $apiName = $api.name\n",
283 | " if ($api.metaData.subType -eq \"PROXY\") {\n",
284 | " $apiCustomPropertiesJson = ConvertTo-Json -InputObject $apiCustomProperties -Depth 10 -Compress\n",
285 | " write-output \"👉🏻 Creating API $apiName\"\n",
286 | " az apic api create -g $resourceGroupName -s $apicResourceName --api-id $apiName --type REST `\n",
287 | " --title $apiName `\n",
288 | " --custom-properties $apiCustomPropertiesJson.replace('\"','\\\"')\n",
289 | " foreach ($revision in $api.revision) {\n",
290 | " write-output \"👉🏻 Creating version $revision of API $apiName\"\n",
291 | " az apic api version create -g $resourceGroupName -s $apicResourceName --api-id $apiName --version-id \"v-$revision\" --title \"Version $revision\" `\n",
292 | " --lifecycle-stage \"production\"\n",
293 | "\n",
294 | " write-output \"👉🏻 Creating definition for version $revision of API $apiName\"\n",
295 | " az apic api definition create -g $resourceGroupName -s $apicResourceName --api-id $apiName `\n",
296 | " --version-id \"v-$revision\" --definition-id \"openapi\" --title \"OpenAPI\" --description \"OpenAPI spec\" \n",
297 | "\n",
298 | " }\n",
299 | " }\n",
300 | "}\n",
301 | "\n"
302 | ]
303 | },
304 | {
305 | "cell_type": "markdown",
306 | "metadata": {},
307 | "source": [
308 | "### 6️⃣ Import the Apigee API Deployments into API Center\n",
309 | "\n",
310 | "Get the Deployments from Apigee and create them in API Center"
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "execution_count": null,
316 | "metadata": {
317 | "dotnet_interactive": {
318 | "language": "pwsh"
319 | },
320 | "polyglot_notebook": {
321 | "kernelName": "pwsh"
322 | },
323 | "vscode": {
324 | "languageId": "polyglot-notebook"
325 | }
326 | },
327 | "outputs": [],
328 | "source": [
329 | "$apigeeDeploymentsListJson = gcloud apigee deployments list --format=json\n",
330 | "$apigeeDeploymentsList = $apigeeDeploymentsListJson | ConvertFrom-Json\n",
331 | "foreach ($apigeeDeployment in $apigeeDeploymentsList) {\n",
332 | " $apiName = $apigeeDeployment.apiProxy\n",
333 | " $envName = $apigeeDeployment.environment\n",
334 | " $apigeeDeploymentJson = gcloud apigee deployments describe --api=$apiName --environment=$envName --format=json\n",
335 | "\n",
336 | " $apigeeDeployment = $apigeeDeploymentJson | ConvertFrom-Json\n",
337 | "\n",
338 | " $deploymentCustomProperties = @{\n",
339 | " \"deployStartTime\" = $apigeeDeployment.deployStartTime\n",
340 | " }\n",
341 | "\n",
342 | " $deploymentCustomPropertiesJson = ConvertTo-Json -InputObject $deploymentCustomProperties -Depth 10 -Compress\n",
343 | " $revision = $apigeeDeployment.revision\n",
344 | " write-output \"👉🏻 Creating deployment for version $revision of API $apiName\"\n",
345 | " az apic api deployment create -g $resourceGroupName -s $apicResourceName --deployment-id \"$apiName-deployment\" `\n",
346 | " --title \"$apiName Deployment\" --api-id $apiName `\n",
347 | " --environment-id \"/workspaces/default/environments/$envName\" `\n",
348 | " --definition-id \"/workspaces/default/apis/another-petstore/versions/v-$revision/definitions/openapi\" `\n",
349 | " --server '{\\\"runtimeUri\\\":[\\\"\\\"]}' `\n",
350 | " --custom-properties $deploymentCustomPropertiesJson.replace('\"','\\\"')\n",
351 | "}"
352 | ]
353 | },
354 | {
355 | "cell_type": "markdown",
356 | "metadata": {},
357 | "source": [
358 | "### 7️⃣ Discover the APIs that were just imported\n",
359 | "\n",
360 | "You can discover the APIs with fhe following methods:\n",
361 | "- With the Azure Portal\n",
362 | "- With the [self-hosted API Center Portal](https://learn.microsoft.com/en-us/azure/api-center/enable-api-center-portal)\n",
363 | "- With the [VS Code extension](https://learn.microsoft.com/en-us/azure/api-center/use-vscode-extension-copilot) that is integrated with GitHub Copilot Chat.\n",
364 | "- With the CLI, the service REST API and more\n",
365 | "\n",
366 | "Here we will use the [list command](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-list) to display the APIs that we have just imported. \n"
367 | ]
368 | },
369 | {
370 | "cell_type": "code",
371 | "execution_count": null,
372 | "metadata": {
373 | "dotnet_interactive": {
374 | "language": "pwsh"
375 | },
376 | "polyglot_notebook": {
377 | "kernelName": "pwsh"
378 | },
379 | "vscode": {
380 | "languageId": "polyglot-notebook"
381 | }
382 | },
383 | "outputs": [],
384 | "source": [
385 | "az apic api list -g $resourceGroupName -s $apicResourceName --query \"[].{Name:name, Title:title, Kind:kind, ContactEmail:contacts[0].email}\" -o table"
386 | ]
387 | },
388 | {
389 | "cell_type": "markdown",
390 | "metadata": {},
391 | "source": [
392 | "### 🗑️ Clean up resources\n",
393 | "\n",
394 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n",
395 | "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that."
396 | ]
397 | }
398 | ],
399 | "metadata": {
400 | "kernelspec": {
401 | "display_name": "Python 3",
402 | "language": "python",
403 | "name": "python3"
404 | },
405 | "language_info": {
406 | "codemirror_mode": {
407 | "name": "ipython",
408 | "version": 3
409 | },
410 | "file_extension": ".py",
411 | "mimetype": "text/x-python",
412 | "name": "python",
413 | "nbconvert_exporter": "python",
414 | "pygments_lexer": "ipython3",
415 | "version": "3.11.9"
416 | }
417 | },
418 | "nbformat": 4,
419 | "nbformat_minor": 2
420 | }
421 |
--------------------------------------------------------------------------------
/labs/import-from-gcp/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-generic-openapi/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Generic OpenAPI lab
4 | 
5 |
6 | Playground to experiment importing APIs in the OpenAPI specification into API Center. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Azure CLI]((https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest)) to import the APIs.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Learning Objectives - Upon completing this lab, you should be able to:
11 | - Deploy Azure API Center using Bicep.
12 | - Configure the API Center metadata scheme for APIs, Environments and Deployments.
13 | - Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).
14 | - Create an enviroment with custom metadata properties
15 | - Register an API using the OpenAPI spec as the source of truth and assign API metadata properties.
16 | - Register an API with individual commands to have full control over all the properties.
17 | - Search and discover the APIs registered in API Center.
18 |
19 | ### Prerequisites
20 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
21 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
22 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
23 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
24 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
25 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
26 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
27 |
28 | ### 🚀 Get started
29 | Proceed by opening the [Jupyter notebook](import-from-generic-openapi.ipynb), and follow the steps provided.
30 |
31 | ### 🗑️ Clean up resources
32 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
33 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-generic-openapi/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-generic-openapi/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-git/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Git version control system
4 | 
5 |
6 | Playground to experiment importing APIs in the OpenAPI specification into API Center by crawling Git repositories.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Learning Objectives - Upon completing this lab, you should be able to:
11 | - Deploy Azure API Center using Bicep.
12 | - Configure the API Center metadata scheme for APIs, Environments and Deployments.
13 | - Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).
14 | - Create an enviroment with custom metadata properties
15 | - Register an API using the OpenAPI spec as the source of truth and assign API metadata properties.
16 | - Register an API with individual commands to have full control over all the properties.
17 | - Search and discover the APIs registered in API Center.
18 |
19 | ### Prerequisites
20 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
21 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
22 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
23 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
24 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
25 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
26 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
27 | - Install [OpenAPI spec validator tool](https://openapi-spec-validator.readthedocs.io/en/latest/index.html)
28 |
29 | ### 🚀 Get started
30 | Proceed by opening the [Jupyter notebook](import-from-generic-openapi.ipynb), and follow the steps provided.
31 |
32 | ### 🗑️ Clean up resources
33 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
34 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-git/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-git/import-from-git.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# API Center ❤️ all APIs\n",
8 | "\n",
9 | "## Import from Git version control system\n",
10 | "\n",
11 | "\n",
12 | "Playground to experiment importing APIs in the OpenAPI specification into API Center by crawling Git repositories.\n",
13 | "\n",
14 | "💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.\n",
15 | "\n",
16 | "### Learning Objectives - Upon completing this lab, you should be able to:\n",
17 | "- Deploy Azure API Center using Bicep.\n",
18 | "- Configure the API Center metadata scheme for APIs, Environments and Deployments.\n",
19 | "- Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).\n",
20 | "- Create an enviroment with custom metadata properties \n",
21 | "- Register an API using the OpenAPI spec as the source of truth and assign API metadata properties.\n",
22 | "- Register an API with individual commands to have full control over all the properties. \n",
23 | "- Search and discover the APIs registered in API Center.\n",
24 | "\n",
25 | "### Prerequisites\n",
26 | "- Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)\n",
27 | "- Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)\n",
28 | "- Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace\n",
29 | "- Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)\n",
30 | "- Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.\n",
31 | "- [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions\n",
32 | "- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)\n",
33 | "- Install [OpenAPI spec validator tool](https://openapi-spec-validator.readthedocs.io/en/latest/index.html)\n"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "### 0️⃣ Initialize notebook variables\n",
41 | "\n",
42 | "- Resources will be suffixed by a unique string based on your subscription id\n",
43 | "- Adjust the APIC location parameter according your preferences and [region availability.](https://learn.microsoft.com/en-us/azure/api-center/overview#available-regions) \n"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "dotnet_interactive": {
51 | "language": "pwsh"
52 | },
53 | "polyglot_notebook": {
54 | "kernelName": "pwsh"
55 | },
56 | "vscode": {
57 | "languageId": "polyglot-notebook"
58 | }
59 | },
60 | "outputs": [],
61 | "source": [
62 | "\n",
63 | "$sourceRepo = \"https://github.com/APIs-guru/openapi-directory\"\n",
64 | "$maxAPIsToImport = 150\n",
65 | "\n",
66 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
67 | "$resourceGroupName = \"lab-$deploymentName\" # change the name to match your naming style\n",
68 | "$resourceGroupLocation = \"westeurope\"\n",
69 | "$apicResourceNamePrefix = \"apic\"\n",
70 | "$apicResourceSku = \"free\"\n",
71 | "$apicResourceTags = @{\n",
72 | " \"lab\" = $deploymentName\n",
73 | "}\n",
74 | "\n",
75 | "# the following metadata will be created during the deployment\n",
76 | "$metadata = @(\n",
77 | ")\n",
78 | "\n",
79 | "# the following environment(s) will be created during the deployment\n",
80 | "$environments = @(\n",
81 | ")\n",
82 | "\n",
83 | "\n",
84 | "Write-Output \"✅ Variables initialized ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "### 1️⃣ Create the Azure Resource Group\n",
92 | "All resources deployed in this lab will be created in the specified resource group. Skip this step if you want to use an existing resource group."
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "metadata": {
99 | "dotnet_interactive": {
100 | "language": "pwsh"
101 | },
102 | "polyglot_notebook": {
103 | "kernelName": "pwsh"
104 | },
105 | "vscode": {
106 | "languageId": "polyglot-notebook"
107 | }
108 | },
109 | "outputs": [],
110 | "source": [
111 | "$resourceGroupOutput = az group create --name $resourceGroupName --location $resourceGroupLocation\n",
112 | "\n",
113 | "if ($LASTEXITCODE -ne 0) {\n",
114 | " Write-Output $resourceGroupOutput\n",
115 | "} else {\n",
116 | " Write-Output \"✅ Azure Resource Grpup $resourceGroupName created ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
117 | "}"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "### 2️⃣ Create deployment using 🦾 Bicep\n",
125 | "\n",
126 | "This lab uses [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declarative define all the resources that will be deployed. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations. "
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {
133 | "dotnet_interactive": {
134 | "language": "pwsh"
135 | },
136 | "polyglot_notebook": {
137 | "kernelName": "pwsh"
138 | },
139 | "vscode": {
140 | "languageId": "polyglot-notebook"
141 | }
142 | },
143 | "outputs": [],
144 | "source": [
145 | "$bicepParameters = @{\n",
146 | " \"`$schema\" = \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\"\n",
147 | " \"contentVersion\" = \"1.0.0.0\"\n",
148 | " \"parameters\" = @{\n",
149 | " \"apicResourceNamePrefix\" = @{ \"value\" = $apicResourceNamePrefix }\n",
150 | " \"apicResourceTags\" = @{ \"value\" = $apicResourceTags }\n",
151 | " \"apicMetadataSchema\" = @{ \"value\" = $metadata }\n",
152 | " \"apicEnvironments\" = @{ \"value\" = $environments }\n",
153 | " }\n",
154 | "}\n",
155 | "\n",
156 | "$bicepParametersJson = ConvertTo-Json -InputObject $bicepParameters -Depth 10\n",
157 | "Set-Content -Path \"params.json\" -Value $bicepParametersJson\n",
158 | "\n",
159 | "# Execute the Azure CLI command to create the deployment\n",
160 | "az deployment group create --name $deploymentName --resource-group $resourceGroupName --template-file \"main.bicep\" --parameters \"params.json\"\n",
161 | "\n"
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "### 3️⃣ Get the deployment outputs\n",
169 | "\n",
170 | "We will set the `apicResourceName` variable with the value that was returned from the deployment "
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {
177 | "dotnet_interactive": {
178 | "language": "pwsh"
179 | },
180 | "polyglot_notebook": {
181 | "kernelName": "pwsh"
182 | },
183 | "vscode": {
184 | "languageId": "polyglot-notebook"
185 | }
186 | },
187 | "outputs": [],
188 | "source": [
189 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apicResourceName.value -o json\n",
190 | "if ($LASTEXITCODE -ne 0) {\n",
191 | " Write-Output $deploymentOutput\n",
192 | "} else {\n",
193 | " $apicResourceName = $deploymentOutput | ConvertFrom-Json\n",
194 | "}\n",
195 | "Write-Output \"👉🏻 API Center name: $apicResourceName\""
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "### 4️⃣ Clone the repo\n",
203 | "\n",
204 | "Creates a local copy of the specific repository or branch within a repository.\n"
205 | ]
206 | },
207 | {
208 | "cell_type": "code",
209 | "execution_count": null,
210 | "metadata": {
211 | "dotnet_interactive": {
212 | "language": "pwsh"
213 | },
214 | "polyglot_notebook": {
215 | "kernelName": "pwsh"
216 | },
217 | "vscode": {
218 | "languageId": "polyglot-notebook"
219 | }
220 | },
221 | "outputs": [],
222 | "source": [
223 | "git clone $sourceRepo \".temp\""
224 | ]
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "### 5️⃣ Crawl APIs and register each one of them in API Center\n",
231 | "\n",
232 | "[Registers](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-register) each valid API in the cloned repo."
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": null,
238 | "metadata": {
239 | "dotnet_interactive": {
240 | "language": "pwsh"
241 | },
242 | "polyglot_notebook": {
243 | "kernelName": "pwsh"
244 | },
245 | "vscode": {
246 | "languageId": "polyglot-notebook"
247 | }
248 | },
249 | "outputs": [],
250 | "source": [
251 | "\n",
252 | "$files = Get-ChildItem -Path \".temp\" -Recurse -File\n",
253 | "\n",
254 | "$counter = 0\n",
255 | "foreach ($file in $files) {\n",
256 | " if ($file.Extension -eq \".yaml\" || $file.Extension -eq \".yml\" || $file.Extension -eq \".json\") {\n",
257 | " $fileSize = $file.Length\n",
258 | " $filePath = $file.FullName\n",
259 | " $validationOutput = openapi-spec-validator $filePath\n",
260 | " if ($LASTEXITCODE -ne 0) {\n",
261 | " Write-Output \"🚫 File: $filePath failed validation againts OpenAPI 2.0 (aka Swagger), OpenAPI 3.0 or OpenAPI 3.1 specification\"\n",
262 | " } else { \n",
263 | " $counter++\n",
264 | " Write-Output \"👉🏻 Registering: $filePath\"\n",
265 | " az apic api register -g $resourceGroupName -s $apicResourceName -l $filePath\n",
266 | " } \n",
267 | " if ($counter -ge $maxAPIsToImport) {\n",
268 | " Write-Output \"🚫 Max APIs to import reached. Done for now.\"\n",
269 | " break\n",
270 | " }\n",
271 | " }\n",
272 | "}\n",
273 | "Write-Output \"✅ $counter APIs imported.\"\n",
274 | "\n"
275 | ]
276 | },
277 | {
278 | "cell_type": "markdown",
279 | "metadata": {},
280 | "source": [
281 | "### 7️⃣ Discover the APIs that were just imported\n",
282 | "\n",
283 | "You can discover the APIs with fhe following methods:\n",
284 | "- With the Azure Portal\n",
285 | "- With the [self-hosted API Center Portal](https://learn.microsoft.com/en-us/azure/api-center/enable-api-center-portal)\n",
286 | "- With the [VS Code extension](https://learn.microsoft.com/en-us/azure/api-center/use-vscode-extension-copilot) that is integrated with GitHub Copilot Chat.\n",
287 | "- With the CLI, the service REST API and more\n",
288 | "\n",
289 | "Here we will use the [list command](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-list) to display the APIs that we have just imported. \n"
290 | ]
291 | },
292 | {
293 | "cell_type": "code",
294 | "execution_count": null,
295 | "metadata": {
296 | "dotnet_interactive": {
297 | "language": "pwsh"
298 | },
299 | "polyglot_notebook": {
300 | "kernelName": "pwsh"
301 | },
302 | "vscode": {
303 | "languageId": "polyglot-notebook"
304 | }
305 | },
306 | "outputs": [],
307 | "source": [
308 | "az apic api list -g $resourceGroupName -s $apicResourceName --query \"[].{Name:name, Title:title, ContactEmail:contacts[0].email}\" -o table"
309 | ]
310 | },
311 | {
312 | "cell_type": "markdown",
313 | "metadata": {},
314 | "source": [
315 | "### 🗑️ Clean up resources\n",
316 | "\n",
317 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n",
318 | "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that."
319 | ]
320 | }
321 | ],
322 | "metadata": {
323 | "kernelspec": {
324 | "display_name": "Python 3",
325 | "language": "python",
326 | "name": "python3"
327 | },
328 | "language_info": {
329 | "codemirror_mode": {
330 | "name": "ipython",
331 | "version": 3
332 | },
333 | "file_extension": ".py",
334 | "mimetype": "text/x-python",
335 | "name": "python",
336 | "nbconvert_exporter": "python",
337 | "pygments_lexer": "ipython3",
338 | "version": "3.11.9"
339 | }
340 | },
341 | "nbformat": 4,
342 | "nbformat_minor": 2
343 | }
344 |
--------------------------------------------------------------------------------
/labs/import-from-git/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-ibm/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from IBM® API Connect
4 |
5 | 
6 |
7 | Playground to experiment bulk importing APIs from IBM API Connect. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [IBM API Connect Tooklit](https://www.ibm.com/docs/en/api-connect/10.0.8?topic=tool-overview-command-line) to export the APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center.
8 |
9 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
10 |
11 | ### Learning Objectives - Upon completing this lab, you should be able to
12 |
13 | - Deploy Azure API Center using Bicep.
14 | - Configure the API Center metadata scheme for APIs, Environments and Deployments.
15 | - Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).
16 | - Register APIs using the OpenAPI spec exported from IBM API Connect.
17 | - Create deployments for each IBM API Connect Gateway.
18 | - Search and discover the APIs registered in API Center.
19 |
20 | ### Prerequisites
21 |
22 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
23 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
24 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
25 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
26 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
27 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
28 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
29 | - Install or update to the latest [IBM API Connect Toolkit](https://www.ibm.com/docs/en/api-connect/10.0.8?topic=configuration-installing-toolkit)
30 | - [Logging in to a management server](https://www.ibm.com/docs/en/api-connect/10.0.8?topic=tool-logging-in-management-server)
31 |
32 | ### 🚀 Get started
33 |
34 | Proceed by opening the [Jupyter notebook](import-from-ibm.ipynb), and follow the steps provided.
35 |
36 | ### 🗑️ Clean up resources
37 |
38 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
39 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
40 |
--------------------------------------------------------------------------------
/labs/import-from-ibm/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-ibm/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-k8s/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Kubernetes
4 | 
5 |
6 | Work in progress
7 |
8 | ### Prerequisites
9 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
10 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
11 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
12 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
13 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
14 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
15 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
16 |
17 | ### 🚀 Get started
18 | Proceed by opening the [Jupyter notebook](import-from-k8s.ipynb), and follow the steps provided.
19 |
20 | ### 🗑️ Clean up resources
21 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
22 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-k8s/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-kong/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from Kong API Gateway
4 | 
5 |
6 | Playground to experiment importing APIs from Kong API Gateway. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Kong Admin API](https://docs.konghq.com/gateway/api/admin-oss/latest) to export Kong services and import them into API Center.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Learning Objectives - Upon completing this lab, you should be able to:
11 | - Deploy Azure API Center using Bicep.
12 | - Configure the API Center metadata scheme for APIs, Environments and Deployments.
13 | - Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).
14 | - Create an enviroment with custom metadata properties
15 | - Register an API using the OpenAPI spec as the source of truth and assign API metadata properties.
16 | - Register an API with individual commands to have full control over all the properties.
17 | - Search and discover the APIs registered in API Center.
18 |
19 | ### Prerequisites
20 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
21 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
22 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
23 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
24 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
25 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
26 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
27 |
28 | ### 🚀 Get started
29 | Proceed by opening the [Jupyter notebook](import-from-generic-openapi.ipynb), and follow the steps provided.
30 |
31 | ### 🗑️ Clean up resources
32 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
33 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-kong/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-kong/import-from-kong.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# API Center ❤️ all APIs\n",
8 | "\n",
9 | "## Import from Kong API Gateway\n",
10 | "\n",
11 | "\n",
12 | "Playground to experiment importing APIs from Kong API Gateway. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Kong Admin API](https://docs.konghq.com/gateway/api/admin-oss/latest) to export Kong services and import them into API Center.\n",
13 | "\n",
14 | "💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.\n",
15 | "\n",
16 | "### Learning Objectives - Upon completing this lab, you should be able to:\n",
17 | "- Deploy Azure API Center using Bicep.\n",
18 | "- Configure the API Center metadata scheme for APIs, Environments and Deployments.\n",
19 | "- Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).\n",
20 | "- Create an enviroment with custom metadata properties \n",
21 | "- Register an API using the OpenAPI spec as the source of truth and assign API metadata properties.\n",
22 | "- Register an API with individual commands to have full control over all the properties. \n",
23 | "- Search and discover the APIs registered in API Center.\n",
24 | "\n",
25 | "### Prerequisites\n",
26 | "- Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)\n",
27 | "- Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)\n",
28 | "- Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace\n",
29 | "- Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)\n",
30 | "- Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.\n",
31 | "- [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions\n",
32 | "- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)\n"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "### 0️⃣ Initialize notebook variables\n",
40 | "\n",
41 | "- Resources will be suffixed by a unique string based on your subscription id\n",
42 | "- Adjust the APIC location parameter according your preferences and [region availability.](https://learn.microsoft.com/en-us/azure/api-center/overview#available-regions) \n"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {
49 | "dotnet_interactive": {
50 | "language": "pwsh"
51 | },
52 | "polyglot_notebook": {
53 | "kernelName": "pwsh"
54 | },
55 | "vscode": {
56 | "languageId": "polyglot-notebook"
57 | }
58 | },
59 | "outputs": [],
60 | "source": [
61 | "\n",
62 | "$kongAdminAPIUrl = \"http://localhost:8001\"\n",
63 | "\n",
64 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
65 | "$resourceGroupName = \"lab-$deploymentName\" # change the name to match your naming style\n",
66 | "$resourceGroupLocation = \"westeurope\"\n",
67 | "$apicResourceNamePrefix = \"apic\"\n",
68 | "$apicResourceSku = \"free\"\n",
69 | "$apicResourceTags = @{\n",
70 | " \"lab\" = $deploymentName\n",
71 | "}\n",
72 | "\n",
73 | "# the following metadata will be created during the deployment\n",
74 | "$metadata = @(\n",
75 | " @{\n",
76 | " \"name\" = 'kongVersion'\n",
77 | " \"schema\" = '{\"title\":\"kongVersion\",\"description\":\"The Kong API Gateway version\",\"type\":\"string\"}'\n",
78 | " \"assignedTo\" = @(\n",
79 | " @{\n",
80 | " \"entity\" = 'environment'\n",
81 | " \"required\" = $false\n",
82 | " }\n",
83 | " )\n",
84 | " },\n",
85 | " @{\n",
86 | " \"name\" = 'kongEdition'\n",
87 | " \"schema\" = '{\"title\":\"kongEdition\",\"description\":\"The Kong API Gateway edition\",\"type\":\"string\"}'\n",
88 | " \"assignedTo\" = @(\n",
89 | " @{\n",
90 | " \"entity\" = 'environment'\n",
91 | " \"required\" = $false\n",
92 | " }\n",
93 | " )\n",
94 | " },\n",
95 | " @{\n",
96 | " \"name\" = 'konnectMode'\n",
97 | " \"schema\" = '{\"title\":\"konnectMode\",\"description\":\"Using Kong Konnectn\",\"type\":\"boolean\"}'\n",
98 | " \"assignedTo\" = @(\n",
99 | " @{\n",
100 | " \"entity\" = 'environment'\n",
101 | " \"required\" = $false\n",
102 | " }\n",
103 | " )\n",
104 | " },\n",
105 | " @{\n",
106 | " \"name\" = 'upstreamHost'\n",
107 | " \"schema\" = '{\"title\":\"host\",\"description\":\"Upstream server\",\"type\":\"string\"}'\n",
108 | " \"assignedTo\" = @(\n",
109 | " @{\n",
110 | " \"entity\" = 'api'\n",
111 | " \"required\" = $false\n",
112 | " }\n",
113 | " )\n",
114 | " },\n",
115 | " @{\n",
116 | " \"name\" = 'apiEnabled'\n",
117 | " \"schema\" = '{\"title\":\"apiEnabled\",\"description\":\"The API is enabled\",\"type\":\"boolean\"}'\n",
118 | " \"assignedTo\" = @(\n",
119 | " @{\n",
120 | " \"entity\" = 'api'\n",
121 | " \"required\" = $false\n",
122 | " }\n",
123 | " )\n",
124 | " },\n",
125 | " @{\n",
126 | " \"name\" = 'tags'\n",
127 | " \"schema\" = '{\"title\":\"tags\",\"description\":\"API tags\",\"type\":\"array\",\"items\":{\"type\":\"string\"}}'\n",
128 | " \"assignedTo\" = @(\n",
129 | " @{\n",
130 | " \"entity\" = 'api'\n",
131 | " \"required\" = $false\n",
132 | " }\n",
133 | " )\n",
134 | " },\n",
135 | " @{\n",
136 | " \"name\" = 'protocol'\n",
137 | " \"schema\" = '{\"title\":\"protocol\",\"description\":\"The API deployment protocol\",\"type\":\"boolean\"}'\n",
138 | " \"assignedTo\" = @(\n",
139 | " @{\n",
140 | " \"entity\" = 'deployment'\n",
141 | " \"required\" = $false\n",
142 | " }\n",
143 | " )\n",
144 | " } \n",
145 | ")\n",
146 | "\n",
147 | "\n",
148 | "# the following environment(s) will be created during the deployment\n",
149 | "$environments = @(\n",
150 | " @{\n",
151 | " \"title\" = 'dev'\n",
152 | " \"kind\" = 'development'\n",
153 | " \"description\" = 'Dev Environment'\n",
154 | " \"server\" = @{\n",
155 | " \"type\" = 'Kong API Gateway' \n",
156 | " \"managementPortalUri\" = 'https://localhost:8002/'\n",
157 | " }\n",
158 | " \"onboarding\" = @{\n",
159 | " \"developerPortalUri\" = ''\n",
160 | " \"instructions\" = ''\n",
161 | " }\n",
162 | " \"customProperties\" = @{ \n",
163 | " }\n",
164 | " }\n",
165 | ")\n",
166 | "\n",
167 | "\n",
168 | "\n",
169 | "Write-Output \"✅ Variables initialized ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n"
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "### 1️⃣ Create the Azure Resource Group\n",
177 | "All resources deployed in this lab will be created in the specified resource group. Skip this step if you want to use an existing resource group."
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {
184 | "dotnet_interactive": {
185 | "language": "pwsh"
186 | },
187 | "polyglot_notebook": {
188 | "kernelName": "pwsh"
189 | },
190 | "vscode": {
191 | "languageId": "polyglot-notebook"
192 | }
193 | },
194 | "outputs": [],
195 | "source": [
196 | "$resourceGroupOutput = az group create --name $resourceGroupName --location $resourceGroupLocation\n",
197 | "\n",
198 | "if ($LASTEXITCODE -ne 0) {\n",
199 | " Write-Output $resourceGroupOutput\n",
200 | "} else {\n",
201 | " Write-Output \"✅ Azure Resource Grpup $resourceGroupName created ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
202 | "}"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "metadata": {},
208 | "source": [
209 | "### 2️⃣ Create deployment using 🦾 Bicep\n",
210 | "\n",
211 | "This lab uses [Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) to declarative define all the resources that will be deployed. Change the parameters or the [main.bicep](main.bicep) directly to try different configurations. "
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {
218 | "dotnet_interactive": {
219 | "language": "pwsh"
220 | },
221 | "polyglot_notebook": {
222 | "kernelName": "pwsh"
223 | },
224 | "vscode": {
225 | "languageId": "polyglot-notebook"
226 | }
227 | },
228 | "outputs": [],
229 | "source": [
230 | "$bicepParameters = @{\n",
231 | " \"`$schema\" = \"https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#\"\n",
232 | " \"contentVersion\" = \"1.0.0.0\"\n",
233 | " \"parameters\" = @{\n",
234 | " \"apicResourceNamePrefix\" = @{ \"value\" = $apicResourceNamePrefix }\n",
235 | " \"apicResourceTags\" = @{ \"value\" = $apicResourceTags }\n",
236 | " \"apicMetadataSchema\" = @{ \"value\" = $metadata }\n",
237 | " \"apicEnvironments\" = @{ \"value\" = $environments }\n",
238 | " }\n",
239 | "}\n",
240 | "\n",
241 | "$bicepParametersJson = ConvertTo-Json -InputObject $bicepParameters -Depth 10\n",
242 | "Set-Content -Path \"params.json\" -Value $bicepParametersJson\n",
243 | "\n",
244 | "# Execute the Azure CLI command to create the deployment\n",
245 | "az deployment group create --name $deploymentName --resource-group $resourceGroupName --template-file \"main.bicep\" --parameters \"params.json\"\n",
246 | "\n"
247 | ]
248 | },
249 | {
250 | "cell_type": "markdown",
251 | "metadata": {},
252 | "source": [
253 | "### 3️⃣ Get the deployment outputs\n",
254 | "\n",
255 | "We will set the `apicResourceName` variable with the value that was returned from the deployment "
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": null,
261 | "metadata": {
262 | "dotnet_interactive": {
263 | "language": "pwsh"
264 | },
265 | "polyglot_notebook": {
266 | "kernelName": "pwsh"
267 | },
268 | "vscode": {
269 | "languageId": "polyglot-notebook"
270 | }
271 | },
272 | "outputs": [],
273 | "source": [
274 | "$deploymentOutput = az deployment group show --name $deploymentName -g $resourceGroupName --query properties.outputs.apicResourceName.value -o json\n",
275 | "if ($LASTEXITCODE -ne 0) {\n",
276 | " Write-Output $deploymentOutput\n",
277 | "} else {\n",
278 | " $apicResourceName = $deploymentOutput | ConvertFrom-Json\n",
279 | "}\n",
280 | "Write-Output \"👉🏻 API Center name: $apicResourceName\""
281 | ]
282 | },
283 | {
284 | "cell_type": "markdown",
285 | "metadata": {},
286 | "source": [
287 | "### 4️⃣ Update the environment metadata\n",
288 | "\n",
289 | "We will [update the enviroment](https://learn.microsoft.com/en-us/cli/azure/apic/environment?view=azure-cli-latest#az-apic-environment-update) with the Kong configuration"
290 | ]
291 | },
292 | {
293 | "cell_type": "code",
294 | "execution_count": null,
295 | "metadata": {
296 | "dotnet_interactive": {
297 | "language": "pwsh"
298 | },
299 | "polyglot_notebook": {
300 | "kernelName": "pwsh"
301 | },
302 | "vscode": {
303 | "languageId": "polyglot-notebook"
304 | }
305 | },
306 | "outputs": [],
307 | "source": [
308 | "$config = Invoke-RestMethod -Uri $kongAdminAPIUrl/ -Method Get\n",
309 | "$environmentCustomProperties = @{\n",
310 | " \"kongVersion\" = $config.version\n",
311 | " \"kongEdition\" = $config.edition\n",
312 | " \"konnectMode\" = $config.configuration.konnect_mode\n",
313 | "}\n",
314 | "\n",
315 | "$environmentCustomPropertiesJson = ConvertTo-Json -InputObject $environmentCustomProperties -Depth 10 -Compress\n",
316 | "\n",
317 | "az apic environment update -g $resourceGroupName -s $apicResourceName --environment-id \"dev\" `\n",
318 | " --custom-properties $environmentCustomPropertiesJson.replace('\"','\\\"')"
319 | ]
320 | },
321 | {
322 | "cell_type": "markdown",
323 | "metadata": {},
324 | "source": [
325 | "### 5️⃣ Retrieves the Kong services and import into API Center\n",
326 | "\n",
327 | "It uses the [Kong Admin API](https://docs.konghq.com/gateway/latest/get-started/services-and-routes/) to retrieve the services and then the Azure CLI to import the APIs into API Center."
328 | ]
329 | },
330 | {
331 | "cell_type": "code",
332 | "execution_count": null,
333 | "metadata": {
334 | "dotnet_interactive": {
335 | "language": "pwsh"
336 | },
337 | "polyglot_notebook": {
338 | "kernelName": "pwsh"
339 | },
340 | "vscode": {
341 | "languageId": "polyglot-notebook"
342 | }
343 | },
344 | "outputs": [],
345 | "source": [
346 | "\n",
347 | "$services = Invoke-RestMethod -Uri $kongAdminAPIUrl/services -Method Get\n",
348 | "\n",
349 | "foreach ($service in $services.data) {\n",
350 | " $apiCustomProperties = @{\n",
351 | " \"upstreamHost\" = $service.host\n",
352 | " \"apiEnabled\" = $service.enabled\n",
353 | " \"tags\" = $service.tags\n",
354 | " }\n",
355 | "\n",
356 | " $apiId = $service.name\n",
357 | " $apiName = $service.name\n",
358 | " $apiVersionId = \"1-0\"\n",
359 | " $apiVersionName = \"1.0\"\n",
360 | " $definitionId = \"openapi\"\n",
361 | "\n",
362 | " $apiCustomPropertiesJson = ConvertTo-Json -InputObject $apiCustomProperties -Depth 10 -Compress\n",
363 | " write-output \"👉🏻 Creating API $apiName\"\n",
364 | " az apic api create -g $resourceGroupName -s $apicResourceName --api-id $apiId --type REST `\n",
365 | " --title $apiName `\n",
366 | " --custom-properties $apiCustomPropertiesJson.replace('\"','\\\"')\n",
367 | "\n",
368 | " write-output \"👉🏻 Creating version $apiVersion of API $apiName\"\n",
369 | " az apic api version create -g $resourceGroupName -s $apicResourceName --api-id $apiId --version-id $apiVersionId `\n",
370 | " --title $apiVersionName --lifecycle-stage \"development\"\n",
371 | "\n",
372 | " write-output \"👉🏻 Creating definition for version $apiVersion of API $apiName\"\n",
373 | " az apic api definition create -g $resourceGroupName -s $apicResourceName --api-id $apiId `\n",
374 | " --version-id $apiVersionId --definition-id $definitionId --title \"OpenAPI\" --description \"OpenAPI spec\" \n",
375 | "\n",
376 | " $deploymentCustomProperties = @{\n",
377 | " \"protocol\" = $service.protocol\n",
378 | " }\n",
379 | " \n",
380 | " $deploymentCustomPropertiesJson = ConvertTo-Json -InputObject $deploymentCustomProperties -Depth 10 -Compress\n",
381 | " write-output \"👉🏻 Creating deployment for the API $apiName\"\n",
382 | " az apic api deployment create -g $resourceGroupName -s $apicResourceName --deployment-id \"deployment\" `\n",
383 | " --title \"Development deployment\" --description \"Development deployment.\" --api-id $apiId `\n",
384 | " --environment-id \"/workspaces/default/environments/dev\" `\n",
385 | " --definition-id \"/workspaces/default/apis/another-petstore/versions/$apiVersionId/definitions/$definitionId\" `\n",
386 | " --server '{\\\"runtimeUri\\\":[\\\"http://localhost:8000\\\"]}' `\n",
387 | " --custom-properties $deploymentCustomPropertiesJson.replace('\"','\\\"')\n",
388 | "\n",
389 | "\n",
390 | "}"
391 | ]
392 | },
393 | {
394 | "cell_type": "markdown",
395 | "metadata": {},
396 | "source": [
397 | "### 6️⃣ Discover the APIs that were just imported\n",
398 | "\n",
399 | "You can discover the APIs with fhe following methods:\n",
400 | "- With the Azure Portal\n",
401 | "- With the [self-hosted API Center Portal](https://learn.microsoft.com/en-us/azure/api-center/enable-api-center-portal)\n",
402 | "- With the [VS Code extension](https://learn.microsoft.com/en-us/azure/api-center/use-vscode-extension-copilot) that is integrated with GitHub Copilot Chat.\n",
403 | "- With the CLI, the service REST API and more\n",
404 | "\n",
405 | "Here we will use the [list command](https://learn.microsoft.com/en-us/cli/azure/apic/api?view=azure-cli-latest#az-apic-api-list) to display the APIs that we have just imported. \n"
406 | ]
407 | },
408 | {
409 | "cell_type": "code",
410 | "execution_count": null,
411 | "metadata": {
412 | "dotnet_interactive": {
413 | "language": "pwsh"
414 | },
415 | "polyglot_notebook": {
416 | "kernelName": "pwsh"
417 | },
418 | "vscode": {
419 | "languageId": "polyglot-notebook"
420 | }
421 | },
422 | "outputs": [],
423 | "source": [
424 | "az apic api list -g $resourceGroupName -s $apicResourceName --query \"[].{Name:name, Title:title, Kind:kind, ContactEmail:contacts[0].email}\" -o table"
425 | ]
426 | },
427 | {
428 | "cell_type": "markdown",
429 | "metadata": {},
430 | "source": [
431 | "### 🗑️ Clean up resources\n",
432 | "\n",
433 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.\n",
434 | "Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that."
435 | ]
436 | }
437 | ],
438 | "metadata": {
439 | "kernelspec": {
440 | "display_name": "Python 3",
441 | "language": "python",
442 | "name": "python3"
443 | },
444 | "language_info": {
445 | "codemirror_mode": {
446 | "name": "ipython",
447 | "version": 3
448 | },
449 | "file_extension": ".py",
450 | "mimetype": "text/x-python",
451 | "name": "python",
452 | "nbconvert_exporter": "python",
453 | "pygments_lexer": "ipython3",
454 | "version": "3.11.9"
455 | }
456 | },
457 | "nbformat": 4,
458 | "nbformat_minor": 2
459 | }
460 |
--------------------------------------------------------------------------------
/labs/import-from-kong/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-mulesoft/README.MD:
--------------------------------------------------------------------------------
1 | # API Center ❤️ all APIs
2 |
3 | ## Import from MuleSoft API Manager
4 | 
5 |
6 | Playground to experiment importing APIs from the MuleSoft Anypoint platform. We start by creating an API Center instance using [Bicep resource definition](https://learn.microsoft.com/en-us/azure/templates/microsoft.apicenter/services?pivots=deployment-language-bicep) and then we will use the [Anypoint Platform CLI](https://docs.mulesoft.com/anypoint-cli/latest/) to export the APIs and the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) to import the APIs into API Center.
7 |
8 | 💡 Every step outlined below leverages the power of PowerShell scripts. This is designed so you can seamlessly integrate them into your automation workflows, CI/CD pipelines, webhooks, and more.
9 |
10 | ### Learning Objectives - Upon completing this lab, you should be able to:
11 | - Deploy Azure API Center using Bicep.
12 | - Configure the API Center metadata scheme for APIs, Environments and Deployments.
13 | - Understand the Azure CLI commands to manage Azure API Center. [Full list of commands available here](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest).
14 | - Create an enviroment with custom metadata properties
15 | - Register an API using the OpenAPI spec as the source of truth and assign API metadata properties.
16 | - Register an API with individual commands to have full control over all the properties.
17 | - Search and discover the APIs registered in API Center.
18 |
19 | ### Prerequisites
20 | - Install or update to the latest [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download)
21 | - Install or update to the latest [Visual Studio Code](https://code.visualstudio.com/)
22 | - Install the [Polyglot Notebooks extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) from the VS Code marketplace
23 | - Install or update to the latest [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell)
24 | - Install or update to the latest [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). The Azure API Center extension will automatically install the first time you run an [az apic](https://learn.microsoft.com/en-us/cli/azure/apic?view=azure-cli-latest) command.
25 | - [An Azure Subscription](https://azure.microsoft.com/en-us/free/) with Contributor permissions
26 | - [Sign in to Azure with Azure CLI](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively)
27 | - [Install and configure the MuleSoft Anypoint Platform CLI](https://docs.mulesoft.com/anypoint-cli/latest/)
28 |
29 | ### 🚀 Get started
30 | Proceed by opening the [Jupyter notebook](import-from-generic-openapi.ipynb), and follow the steps provided.
31 |
32 | ### 🗑️ Clean up resources
33 | When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered.
34 | Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that.
--------------------------------------------------------------------------------
/labs/import-from-mulesoft/account_environment_list.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "environment-id1",
4 | "name": "Design",
5 | "organizationId": "organizationid-guid",
6 | "isProduction": false,
7 | "type": "design",
8 | "clientId": "clientid-guid",
9 | "arcNamespace": null
10 | },
11 | {
12 | "id": "environment-id2",
13 | "name": "Sandbox",
14 | "organizationId": "organizationid-guid",
15 | "isProduction": false,
16 | "type": "sandbox",
17 | "clientId": "clientid2-guid",
18 | "arcNamespace": null
19 | }
20 | ]
--------------------------------------------------------------------------------
/labs/import-from-mulesoft/api-mgr_api_list.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "audit": {
4 | "created": {
5 | "date": "2024-05-03T09:49:53.908Z"
6 | },
7 | "updated": {}
8 | },
9 | "masterOrganizationId": "5c887b3a-13a5-4808-97ae-2fae71667035",
10 | "organizationId": "5c887b3a-13a5-4808-97ae-2fae71667035",
11 | "id": 19461143,
12 | "instanceLabel": null,
13 | "groupId": "5c887b3a-13a5-4808-97ae-2fae71667035",
14 | "assetId": "petstore",
15 | "assetVersion": "1.0.0",
16 | "productVersion": "v1",
17 | "description": null,
18 | "tags": [],
19 | "order": 1,
20 | "providerId": null,
21 | "deprecated": false,
22 | "lastActiveDate": "2024-05-03T12:37:12.354Z",
23 | "endpointUri": null,
24 | "environmentId": "e66fe03d-f76e-41eb-8b6e-cc5456e11466",
25 | "isPublic": false,
26 | "stage": "release",
27 | "technology": "mule4",
28 | "status": "active",
29 | "deployment": {
30 | "audit": {
31 | "created": {},
32 | "updated": {}
33 | },
34 | "applicationId": "26f72364-8300-4c74-b706-5a7d172a6aa6",
35 | "targetId": "cloudhub-us-east-2",
36 | "expectedStatus": "deployed"
37 | },
38 | "lastActiveDelta": 48,
39 | "pinned": false,
40 | "activeContractsCount": 0,
41 | "autodiscoveryInstanceName": "v1:19461143"
42 | }
43 | ]
--------------------------------------------------------------------------------
/labs/import-from-mulesoft/clean-up-resources.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "### 🗑️ Clean up resources\n",
8 | "\n",
9 | "When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered."
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "metadata": {
16 | "dotnet_interactive": {
17 | "language": "pwsh"
18 | },
19 | "polyglot_notebook": {
20 | "kernelName": "pwsh"
21 | },
22 | "vscode": {
23 | "languageId": "polyglot-notebook"
24 | }
25 | },
26 | "outputs": [],
27 | "source": [
28 | "$deploymentName = Split-Path -Path (Get-Location) -Leaf\n",
29 | "$resourceGroupName = \"lab-$deploymentName\"\n",
30 | "\n",
31 | "$deleteOutput = az group delete --name $resourceGroupName -y\n",
32 | "if ($LASTEXITCODE -ne 0) {\n",
33 | " Write-Output $deleteOutput\n",
34 | "} else {\n",
35 | " Write-Output \"✅ Resource group $resourceGroupName deleted ⌚ $(Get-Date -Format 'HH:mm:ss')\"\n",
36 | "}\n"
37 | ]
38 | }
39 | ],
40 | "metadata": {
41 | "kernelspec": {
42 | "display_name": "Python 3",
43 | "language": "python",
44 | "name": "python3"
45 | },
46 | "language_info": {
47 | "codemirror_mode": {
48 | "name": "ipython",
49 | "version": 3
50 | },
51 | "file_extension": ".py",
52 | "mimetype": "text/x-python",
53 | "name": "python",
54 | "nbconvert_exporter": "python",
55 | "pygments_lexer": "ipython3",
56 | "version": "3.11.9"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 2
61 | }
62 |
--------------------------------------------------------------------------------
/labs/import-from-mulesoft/main.bicep:
--------------------------------------------------------------------------------
1 |
2 | @description('The prefix name of the API Center resource')
3 | param apicResourceNamePrefix string
4 |
5 | @description('Location for the API Center resource')
6 | param apicResourceLocation string = resourceGroup().location
7 |
8 | @description('Tags for the API Center resource')
9 | param apicResourceTags object
10 |
11 | @description('API Center Metadata Schema')
12 | param apicMetadataSchema array = []
13 |
14 | @description('API Center Environments')
15 | param apicEnvironments array = []
16 |
17 |
18 | var resourceSuffix = uniqueString(subscription().id, resourceGroup().id)
19 |
20 | resource apic 'Microsoft.ApiCenter/services@2024-03-01' = {
21 | name: '${apicResourceNamePrefix}-${resourceSuffix}'
22 | location: apicResourceLocation
23 | tags: apicResourceTags
24 | identity: {
25 | type: 'SystemAssigned'
26 | }
27 | }
28 |
29 | resource apicMetadata 'Microsoft.ApiCenter/services/metadataSchemas@2024-03-01' = [for metadata in apicMetadataSchema: {
30 | name: metadata.name
31 | parent: apic
32 | properties: {
33 | schema: metadata.schema
34 | assignedTo: [for assignedTo in metadata.assignedTo: {
35 | deprecated: false
36 | entity: assignedTo.entity
37 | required: assignedTo.required
38 | }
39 | ]
40 | }
41 | }]
42 |
43 | resource apicWorkspace 'Microsoft.ApiCenter/services/workspaces@2024-03-01' existing = {
44 | name: 'default'
45 | parent: apic
46 | }
47 |
48 | resource symbolicname 'Microsoft.ApiCenter/services/workspaces/environments@2024-03-01' = [for environment in apicEnvironments: {
49 | name: environment.title
50 | parent: apicWorkspace
51 | properties: {
52 | customProperties: environment.customProperties
53 | description: environment.description
54 | kind: environment.kind
55 | onboarding: {
56 | developerPortalUri: [
57 | environment.onboarding.developerPortalUri
58 | ]
59 | instructions: environment.onboarding.instructions
60 | }
61 | server: {
62 | managementPortalUri: [
63 | environment.server.managementPortalUri
64 | ]
65 | type: environment.server.type
66 | }
67 | title: environment.title
68 | }
69 | }]
70 |
71 | output apicResourceId string = apic.id
72 | output apicResourceName string = apic.name
73 | output apicResourcePrincipalId string = apic.identity.principalId
74 |
75 |
--------------------------------------------------------------------------------
/labs/import-from-mulesoft/runtime-mgr-application_describe.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "26f72364-8300-4c74-b706-5a7d172a6aa6",
3 | "name": "proxyapp",
4 | "creationDate": 1714729803866,
5 | "lastModifiedDate": 1714733433281,
6 | "target": {
7 | "provider": "MC",
8 | "targetId": "cloudhub-us-east-2",
9 | "deploymentSettings": {
10 | "http": {
11 | "inbound": {
12 | "publicUrl": "https://proxyapp-ojrtol.5sc6y6-3.usa-e2.cloudhub.io",
13 | "lastMileSecurity": false,
14 | "forwardSslSession": false
15 | }
16 | },
17 | "runtimeVersion": "4.6.2:5e-java8",
18 | "runtimeReleaseChannel": "EDGE",
19 | "disableAmLogForwarding": false,
20 | "anypointMonitoringScope": "app",
21 | "sidecars": {
22 | "anypoint-monitoring": {
23 | "image": "auto",
24 | "resources": {
25 | "cpu": {
26 | "limit": "50m",
27 | "reserved": "0m"
28 | },
29 | "memory": {
30 | "limit": "50Mi",
31 | "reserved": "50Mi"
32 | }
33 | }
34 | }
35 | },
36 | "runtime": {
37 | "version": "4.6.2:5e-java8",
38 | "releaseChannel": "EDGE",
39 | "java": "8"
40 | }
41 | },
42 | "replicas": 1
43 | },
44 | "status": "APPLIED",
45 | "application": {
46 | "status": "RUNNING",
47 | "desiredState": "STARTED",
48 | "ref": {
49 | "groupId": "5c887b3a-13a5-4808-97ae-2fae71667035",
50 | "artifactId": "petstore-api-gateway-sample-rest-proxy",
51 | "version": "1.0.0-3.2.0",
52 | "packaging": "jar"
53 | },
54 | "configuration": {
55 | "mule.agent.application.properties.service": {
56 | "applicationName": "proxyapp",
57 | "properties": {
58 | "anypoint.platform.analytics_base_uri": "https://analytics-ingest.anypoint.mulesoft.com",
59 | "proxy.port": "8081",
60 | "api.version": "v1:19461143",
61 | "proxy.path": "/*",
62 | "implementation.port": "443",
63 | "implementation.api.parser": "AUTO",
64 | "api.name": "groupId:5c887b3a-13a5-4808-97ae-2fae71667035:assetId:petstore",
65 | "anypoint.platform.base_uri": "https://anypoint.mulesoft.com",
66 | "api.id": "19461143",
67 | "implementation.host": "petstore3.swagger.io",
68 | "anypoint.platform.client_id": "d5e19b6219494ed984d592ae13471039",
69 | "validation.strict.queryParams": "false",
70 | "implementation.protocol": "HTTPS",
71 | "validation.disable": "true",
72 | "validation.strict.headers": "false",
73 | "implementation.path": "/api/v3",
74 | "proxy.responseTimeout": "10000"
75 | },
76 | "secureProperties": {
77 | "anypoint.platform.client_secret": "******"
78 | }
79 | }
80 | },
81 | "vCores": 0.1
82 | },
83 | "desiredVersion": "6ea98620-58e8-408b-a23d-098fc4b03f4b",
84 | "replicas": [
85 | {
86 | "id": "proxyapp-6ffccd7759-jdzz8",
87 | "state": "STARTED",
88 | "deploymentLocation": "cloudhub-us-east-2",
89 | "currentDeploymentVersion": "6ea98620-58e8-408b-a23d-098fc4b03f4b",
90 | "reason": ""
91 | }
92 | ],
93 | "lastSuccessfulVersion": "6ea98620-58e8-408b-a23d-098fc4b03f4b"
94 | }
--------------------------------------------------------------------------------
/tools/delete-all-apis.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Tool: delete all APIs\n",
8 | "\n"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "### 0️⃣ Initialize notebook variables\n",
16 | "\n"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {
23 | "dotnet_interactive": {
24 | "language": "pwsh"
25 | },
26 | "polyglot_notebook": {
27 | "kernelName": "pwsh"
28 | },
29 | "vscode": {
30 | "languageId": "polyglot-notebook"
31 | }
32 | },
33 | "outputs": [],
34 | "source": [
35 | "$resourceGroupName = \"\"\n",
36 | "$apicResourceName = \"\"\n"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {
43 | "dotnet_interactive": {
44 | "language": "pwsh"
45 | },
46 | "polyglot_notebook": {
47 | "kernelName": "pwsh"
48 | },
49 | "vscode": {
50 | "languageId": "polyglot-notebook"
51 | }
52 | },
53 | "outputs": [],
54 | "source": [
55 | "$apiListJson = az apic api list -g $resourceGroupName -n $apicResourceName\n",
56 | "\n",
57 | "$apiList = $apiListJson | ConvertFrom-Json\n",
58 | "foreach ($api in $apiList) {\n",
59 | " $apiName = $api.name\n",
60 | " Write-Output \"👉🏻 Deleting: $apiName\"\n",
61 | " az apic api delete -g $resourceGroupName -n $apicResourceName -y --api-id=$apiName\n",
62 | "}\n"
63 | ]
64 | }
65 | ],
66 | "metadata": {
67 | "kernelspec": {
68 | "display_name": ".NET (C#)",
69 | "language": "C#",
70 | "name": ".net-csharp"
71 | },
72 | "language_info": {
73 | "codemirror_mode": {
74 | "name": "ipython",
75 | "version": 3
76 | },
77 | "file_extension": ".py",
78 | "mimetype": "text/x-python",
79 | "name": "python",
80 | "nbconvert_exporter": "python",
81 | "pygments_lexer": "ipython3",
82 | "version": "3.11.9"
83 | },
84 | "polyglot_notebook": {
85 | "kernelInfo": {
86 | "defaultKernelName": "csharp",
87 | "items": [
88 | {
89 | "aliases": [],
90 | "name": "csharp"
91 | }
92 | ]
93 | }
94 | }
95 | },
96 | "nbformat": 4,
97 | "nbformat_minor": 2
98 | }
99 |
--------------------------------------------------------------------------------