diff --git a/skills/cloud/apigee_basics/SKILL.md b/skills/cloud/apigee_basics/SKILL.md new file mode 100644 index 0000000000..ad4a9a0fca --- /dev/null +++ b/skills/cloud/apigee_basics/SKILL.md @@ -0,0 +1,89 @@ +--- +name: apigee-basics +description: >- + Manages API proxies, products, developers, and apps on Apigee X/Hybrid. + Don't use for other Google Cloud networking gateways, Apigee Edge legacy, or direct Spanner database connections. +--- + +# Apigee Basics + +Apigee is a full-lifecycle API management platform that enables API developers +and administrators to design, secure, deploy, monitor, and scale APIs. It acts +as an L7 gateway, mediating requests between client applications and backend +services. Apigee is available in two main variants: **Apigee X** (fully-managed +cloud service on Google Cloud) and **Apigee Hybrid** (hybrid cloud deployment +with the runtime hosted in a customer-managed Kubernetes cluster). + +This skill covers the core fundamentals of Apigee, including: + +* **Core Concepts**: Organizations, environments, proxies, products, + developers, and apps. +* **Management Interfaces**: Using the `gcloud` CLI, Helm (for Hybrid), and + the REST API. +* **Development**: API proxy bundle structure and programmatic client + libraries. +* **Automation & Security**: Infrastructure as Code (Terraform), IAM roles, + and security policies (API Key, Spike Arrest, OAuth). +* **AI Integration**: Exposing APIs as Model Context Protocol (MCP) tools. + +## Quick Start + +This quick start demonstrates how to import and deploy a basic hello-world API +proxy using the One Platform REST API. For other management methods, see +[CLI (gcloud/Helm) Usage](references/cli-usage.md) or +[Infrastructure as Code (Terraform)](references/iac-usage.md). + +To deploy using the REST API: + +**1. Authenticate and Set Environment Variables** + +Set up your GCP project credentials and target environment: + +```bash +export PROJECT_ID="your-gcp-project" +export ENV_NAME="your-apigee-environment" +export TOKEN=$(gcloud auth print-access-token) +``` + +**2. Import a Hello-World Proxy Bundle** + +Upload a packaged proxy zip bundle to create a new proxy revision. (Assume you +have a `helloworld.zip` bundle representing a standard proxy config; see +[API Proxy Bundle Structure](references/proxy-bundle-structure.md) for the +required directory layout). + +```bash +curl -X POST "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/apis?action=import&name=helloworld" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @helloworld.zip +``` + +**3. Deploy the Proxy Revision** + +Deploy revision 1 of the `helloworld` proxy to your designated environment: + +```bash +curl -X POST "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/environments/${ENV_NAME}/apis/helloworld/revisions/1/deployments" \ + -H "Authorization: Bearer ${TOKEN}" +``` + +## Reference Directory + +Load the relevant reference based on trigger keywords. Prefer the most specific +match; if ambiguous, ask the user to clarify. + +Task / Guide | Trigger Keywords | Reference +----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------- +Understand architecture & core resources | Apigee X vs Hybrid, environment groups, organization, API proxy, API product, developer, developer app | [core-concepts.md](references/core-concepts.md) +Manage via CLI (gcloud / Helm) | gcloud apigee, Helm, hybrid management, CLI commands, Kubernetes deployment | [cli-usage.md](references/cli-usage.md) +Manage via direct REST API calls | curl API, Apigee REST API, direct HTTP, One Platform API, lifecycle management | [api-usage.md](references/api-usage.md) +Construct & package API proxy bundles | apiproxy folder, proxy bundle, helloworld.xml, proxies/default.xml, targets/default.xml, packaging zip | [proxy-bundle-structure.md](references/proxy-bundle-structure.md) +Programmatically manage via Libraries | Python SDK, Node.js client, Go client, Java client, programmatic management | [client-library-usage.md](references/client-library-usage.md) +Declaratively provision via Terraform | Terraform, IaC, google_apigee_api_proxy, google_apigee_api_product, google_apigee_developer, google_apigee_developer_app | [iac-usage.md](references/iac-usage.md) +Configure IAM & runtime security policies | VerifyAPIKey, SpikeArrest, OAuth v2.0, access token, security roles, IAM permissions | [iam-security.md](references/iam-security.md) +Expose APIs as MCP tools | Model Context Protocol, MCP tools, MCP Discovery Proxy, openapi.yaml servers.url, API Hub MCP | [mcp-in-apigee.md](references/mcp-in-apigee.md) + +*If you need detailed product information not found in these references, use the +[Developer Knowledge MCP server](https://developers.google.com/knowledge/mcp) +`search_documents` tool.* diff --git a/skills/cloud/apigee_basics/references/api-usage.md b/skills/cloud/apigee_basics/references/api-usage.md new file mode 100644 index 0000000000..cfd5688fb1 --- /dev/null +++ b/skills/cloud/apigee_basics/references/api-usage.md @@ -0,0 +1,144 @@ +# Apigee Direct REST API Usage + +Enterprise automation pipelines often call the **Apigee Management API** +directly. This document provides examples of how to interact with Apigee X and +Hybrid resources using HTTP REST calls and `curl`. + +-------------------------------------------------------------------------------- + +## Base Configuration + +* **API Endpoint**: `https://apigee.googleapis.com/v1` +* **Authentication**: Standard Google Cloud OAuth 2.0 Bearer tokens. + +**Set Authorization Header** + +```bash +export ORG="your-apigee-org" +export TOKEN=$(gcloud auth print-access-token) +export AUTH_HEADER="Authorization: Bearer ${TOKEN}" +``` + +-------------------------------------------------------------------------------- + +## 1. API Proxies + +### List API Proxies + +Returns a list of all API proxies configured in the organization. + +```bash +curl -X GET "https://apigee.googleapis.com/v1/organizations/${ORG}/apis" \ + -H "${AUTH_HEADER}" +``` + +### Import an API Proxy Bundle + +Uploads a local ZIP file containing the API proxy configuration files to create +a new proxy revision. + +* `helloworld-bundle.zip` must follow the + [API Proxy Bundle Structure](proxy-bundle-structure.md) directory hierarchy. + +```bash +curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/apis?action=import&name=helloworld" \ + -H "${AUTH_HEADER}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @helloworld-bundle.zip +``` + +### Deploy an API Proxy Revision + +Deploys a specific revision of a proxy to a target environment. + +```bash +export ENV="prod" +export REVISION="1" + +curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/${ENV}/apis/helloworld/revisions/${REVISION}/deployments" \ + -H "${AUTH_HEADER}" +``` + +### Undeploy an API Proxy Revision + +Safely undeploys a revision from an environment. + +```bash +curl -X DELETE "https://apigee.googleapis.com/v1/organizations/${ORG}/environments/${ENV}/apis/helloworld/revisions/${REVISION}/deployments" \ + -H "${AUTH_HEADER}" +``` + +-------------------------------------------------------------------------------- + +## 2. API Products + +### Create an API Product + +Creates an API Product that bundles specific resources and sets access rules. + +```bash +curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/apiproducts" \ + -H "${AUTH_HEADER}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "InternalServicesProduct", + "displayName": "Internal Services Product", + "approvalType": "auto", + "attributes": [ + {"name": "access", "value": "public"} + ], + "environments": ["prod"], + "proxies": ["helloworld"], + "quota": "100", + "quotaInterval": "1", + "quotaTimeUnit": "minute" + }' +``` + +-------------------------------------------------------------------------------- + +## 3. Developers & Developer Apps + +### Register a Developer + +Registers a developer within the organization database. + +```bash +curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/developers" \ + -H "${AUTH_HEADER}" \ + -H "Content-Type: application/json" \ + -d '{ + "email": "alice@example.com", + "firstName": "Alice", + "lastName": "Smith", + "userName": "asmith" + }' +``` + +### Create a Developer App + +Creates an application registered by the developer and binds it to one or more +API Products. This triggers the generation of the client credentials (API Key). + +```bash +curl -X POST "https://apigee.googleapis.com/v1/organizations/${ORG}/developers/alice@example.com/apps" \ + -H "${AUTH_HEADER}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "AliceMobileApp", + "apiProducts": ["InternalServicesProduct"], + "callbackUrl": "https://example.com/callback" + }' +``` + +### Fetch App Credentials (API Key) + +Retrieve the Consumer Key and Consumer Secret generated for the Developer App. + +```bash +curl -X GET "https://apigee.googleapis.com/v1/organizations/${ORG}/developers/alice@example.com/apps/AliceMobileApp" \ + -H "${AUTH_HEADER}" +``` + +* Look for the `credentials` object in the JSON response. The `consumerKey` + value is the key clients must supply when making API calls. diff --git a/skills/cloud/apigee_basics/references/cli-usage.md b/skills/cloud/apigee_basics/references/cli-usage.md new file mode 100644 index 0000000000..bd71042353 --- /dev/null +++ b/skills/cloud/apigee_basics/references/cli-usage.md @@ -0,0 +1,180 @@ +# Apigee CLI Usage + +This document details command-line interfaces (CLIs) for managing Apigee X and +Apigee Hybrid. + +-------------------------------------------------------------------------------- + +## 1. gcloud apigee CLI + +The Google Cloud SDK (`gcloud`) provides commands to interact with the Apigee +control plane. Ensure the `gcloud` CLI is updated and the correct project is +targeted: + +```bash +gcloud components update +gcloud config set project YOUR_GCP_PROJECT_ID +``` + +### Common Commands + +**List Organizations** + +Retrieve Apigee organization details linked to the current project. + +```bash +gcloud apigee organizations list +``` + +**Describe Organization** + +Inspect configuration parameters, environment groups, and billing details. + +```bash +gcloud apigee organizations describe --format=json +``` + +**List Environments** + +List environments associated with the organization. + +```bash +gcloud apigee environments list +``` + +**List API Proxies** + +List API proxies deployed or configured in the organization. + +```bash +gcloud apigee apis list +``` + +**Check Long Running Operations** + +Many Apigee operations (like creating an organization, instances, or environment +groups) are asynchronous and return an Operation ID. You can check their status +using: + +```bash +gcloud apigee operations describe OPERATION_ID +``` + +**Describe Deployments** + +List all active deployments of API proxies across environments: + +```bash +gcloud apigee deployments list +``` + +-------------------------------------------------------------------------------- + +## 2. Helm (Apigee Hybrid only) + +For **Apigee Hybrid**, Helm is the official tool for installing and managing the +runtime components (Synchronizer, Runtime, Cassandra database, Logger) in a +Kubernetes cluster. + +> [!NOTE] The legacy command-line utility `apigeectl` is deprecated as of April +> 17, 2024. All deployments should use Helm. + +### Setup and Context + +Helm interacts with your Kubernetes cluster context (configured via `kubectl`). +Your configuration is defined in a local YAML file (e.g., `overrides.yaml`), +which represents your desired state for the cluster topology. + +### Common Helm Commands + +Apigee Hybrid is installed as a sequence of Helm charts. The general pattern to +install or upgrade a component is: + +```bash +helm upgrade RELEASE_NAME CHART_DIRECTORY/ \ + --install \ + --namespace APIGEE_NAMESPACE \ + --atomic \ + -f overrides.yaml +``` + +* `--install`: Installs the chart if it is not already installed. +* `--atomic`: Rolls back the installation on failure. +* `-f overrides.yaml`: Specifies your custom configuration overrides. + +### Recommended Installation Sequence + +Before installing, you must pull the charts from the Google Artifact Registry: + +```bash +export CHART_REPO=oci://us-docker.pkg.dev/apigee-release/apigee-hybrid-helm-charts +export CHART_VERSION=1.16.0 # Use the latest supported version + +helm pull $CHART_REPO/apigee-operator --version $CHART_VERSION --untar +helm pull $CHART_REPO/apigee-datastore --version $CHART_VERSION --untar +# Pull other charts (apigee-telemetry, apigee-redis, apigee-ingress-manager, apigee-org, apigee-env) +``` + +Install components in the following order: + +1. **Apigee Operator**: Manages Apigee custom resources. + + ```bash + helm upgrade operator apigee-operator/ --install --namespace apigee --atomic -f overrides.yaml + ``` + +2. **Datastore**: Deploys the Cassandra database. + + ```bash + helm upgrade datastore apigee-datastore/ --install --namespace apigee --atomic -f overrides.yaml + ``` + +3. **Telemetry**: Deploys logging and metrics collectors. + + ```bash + helm upgrade telemetry apigee-telemetry/ --install --namespace apigee --atomic -f overrides.yaml + ``` + +4. **Redis**: Deploys data cache. + + ```bash + helm upgrade redis apigee-redis/ --install --namespace apigee --atomic -f overrides.yaml + ``` + +5. **Ingress Manager**: Manages ingress controllers. + + ```bash + helm upgrade ingress-manager apigee-ingress-manager/ --install --namespace apigee --atomic -f overrides.yaml + ``` + +6. **Organization**: Configures organization-level settings. + + ```bash + helm upgrade organization apigee-organization/ --install --namespace apigee --atomic -f overrides.yaml + ``` + +7. **Environment**: Deploys the runtime services for a specific environment. + + ```bash + helm upgrade env-prod apigee-env/ --install --namespace apigee --atomic --set env=prod -f overrides.yaml + ``` + +### Managing overrides.yaml + +The `overrides.yaml` file contains environment-specific settings. Example: + +```yaml +gcpProjectID: my-hybrid-project +k8sCluster: + name: hybrid-gke-cluster + region: us-central1 +org: my-apigee-org +envs: + - name: prod + serviceAccountPaths: + synchronizer: ./keys/my-hybrid-project-apigee-synchronizer.json + runtime: ./keys/my-hybrid-project-apigee-runtime.json + udca: ./keys/my-hybrid-project-apigee-udca.json +cassandra: + replicaCount: 3 +``` diff --git a/skills/cloud/apigee_basics/references/client-library-usage.md b/skills/cloud/apigee_basics/references/client-library-usage.md new file mode 100644 index 0000000000..62377b32db --- /dev/null +++ b/skills/cloud/apigee_basics/references/client-library-usage.md @@ -0,0 +1,203 @@ +# Apigee Client Library Usage + +You can programmatically manage Apigee organizations, environments, proxies, and +products using Google's official client libraries. This document provides basic +integration examples in **Python**, **Node.js**, **Go**, and **Java**. + +The Apigee Management API in client libraries uses the service endpoint +`apigee.googleapis.com`. + +-------------------------------------------------------------------------------- + +## 1. Python + +Ensure the Google API Client library is installed: + +```bash +pip install google-api-python-client google-auth +``` + +### Code Snippet: List API Proxies + +```python +import google.auth +from googleapiclient import discovery + +# Authenticate and construct the Apigee client service +credentials, project = google.auth.default() +service = discovery.build('apigee', 'v1', credentials=credentials) + +org_name = "your-apigee-org" +parent = f"organizations/{org_name}" + +try: + # Invoke the APIs list endpoint + request = service.organizations().apis().list(parent=parent) + response = request.execute() + + proxies = response.get('proxies', []) + print("API Proxies configured in Organization:") + for proxy in proxies: + print(f"- {proxy.get('name')}") +except Exception as e: + print(f"Error calling Apigee API: {e}") +``` + +-------------------------------------------------------------------------------- + +## 2. Node.js + +Ensure the Google APIs package is installed: + +```bash +npm install googleapis +``` + +### Code Snippet: List API Proxies + +```javascript +const { google } = require('googleapis'); + +async function listProxies() { + const orgName = 'your-apigee-org'; + + // Authenticate using Application Default Credentials + const auth = new google.auth.GoogleAuth({ + scopes: ['https://www.googleapis.com/auth/cloud-platform'] + }); + const authClient = await auth.getClient(); + + const apigee = google.apigee({ + version: 'v1', + auth: authClient + }); + + try { + const res = await apigee.organizations.apis.list({ + parent: `organizations/${orgName}` + }); + + const proxies = res.data.proxies || []; + console.log('API Proxies configured in Organization:'); + proxies.forEach(proxy => { + console.log(`- ${proxy.name}`); + }); + } catch (err) { + console.error('Error calling Apigee API:', err); + } +} + +listProxies(); +``` + +-------------------------------------------------------------------------------- + +## 3. Go + +Ensure the Go Apigee package is added: + +```bash +go get google.golang.org/api/apigee/v1 +``` + +### Code Snippet: List API Proxies + +```go +package main + +import ( + "context" + "fmt" + "log" + + "google.golang.org/api/apigee/v1" +) + +func main() { + ctx := context.Background() + orgName := "your-apigee-org" + + // Initialize the Apigee service using default credentials + apigeeService, err := apigee.NewService(ctx) + if err != nil { + log.Fatalf("Failed to initialize Apigee service: %v", err) + } + + parent := fmt.Sprintf("organizations/%s", orgName) + call := apigeeService.Organizations.Apis.List(parent) + + response, err := call.Do() + if err != nil { + log.Fatalf("Failed to list API proxies: %v", err) + } + + fmt.Println("API Proxies configured in Organization:") + for _, proxy := range response.Proxies { + fmt.Printf("- %s\n", proxy.Name) + } +} +``` + +-------------------------------------------------------------------------------- + +## 4. Java + +Ensure the following dependencies are included in your `pom.xml` file: + +```xml + + com.google.apis + google-api-services-apigee + v1-rev20240124-2.0.0 + +``` + +### Code Snippet: List API Proxies + +```java +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.json.gson.GsonFactory; +import com.google.api.services.apigee.v1.Apigee; +import com.google.api.services.apigee.v1.model.GoogleCloudApigeeV1ListApiProxiesResponse; +import com.google.api.services.apigee.v1.model.GoogleCloudApigeeV1ApiProxy; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.auth.http.HttpCredentialsAdapter; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +public class ApigeeListProxies { + public static void main(String[] args) { + String orgName = "your-apigee-org"; + String parent = "organizations/" + orgName; + + try { + // Load Default Credentials + GoogleCredentials credentials = GoogleCredentials.getApplicationDefault(); + HttpCredentialsAdapter requestInitializer = new HttpCredentialsAdapter(credentials); + + // Initialize the Apigee service + Apigee apigeeService = new Apigee.Builder( + GoogleNetHttpTransport.newTrustedTransport(), + GsonFactory.getDefaultInstance(), + requestInitializer) + .setApplicationName("apigee-basics-skill") + .build(); + + GoogleCloudApigeeV1ListApiProxiesResponse response = apigeeService.organizations() + .apis() + .list(parent) + .execute(); + + System.out.println("API Proxies configured in Organization:"); + if (response.getProxies() != null) { + for (GoogleCloudApigeeV1ApiProxy proxy : response.getProxies()) { + System.out.println("- " + proxy.getName()); + } + } + } catch (IOException | GeneralSecurityException e) { + System.err.println("Error calling Apigee API: " + e.getMessage()); + } + } +} +``` diff --git a/skills/cloud/apigee_basics/references/core-concepts.md b/skills/cloud/apigee_basics/references/core-concepts.md new file mode 100644 index 0000000000..13144977cd --- /dev/null +++ b/skills/cloud/apigee_basics/references/core-concepts.md @@ -0,0 +1,109 @@ +# Apigee Core Concepts + +This document introduces the core architectural and lifecycle concepts of the +Apigee platform. + +## 1. Apigee X vs. Apigee Hybrid + +Apigee is designed with a disaggregated plane architecture, separating the +control operations (creation, analytics, deployment) from the runtime proxy +traffic. + +* **Apigee X**: A fully-managed Cloud SaaS platform. Google manages both the + **Control Plane** (UI, APIs, Analytics in a Google-managed GCP project) and + the **Runtime Plane** (the L7 Envoy-based gateway executing policies, hosted + in a tenant project peered with your VPC). +* **Apigee Hybrid**: A hybrid deployment topology. Google manages the + **Control Plane** in the cloud, but the customer hosts and manages the + **Runtime Plane** locally or in their cloud VPC within a Kubernetes cluster + (using GKE, EKS, AKS, or Anthos). + * Communication between planes occurs asynchronously via the Apigee + Synchronizer (ingress configuration sync) and Fluentd/Martini (analytics + data ingestion). + +### Determining Runtime Type (X vs. Hybrid) + +You can identify if an Apigee organization is managed (Apigee X) or hybrid using +the following methods: + +1. **Google Cloud Console**: + * Navigate to **Apigee > Management > Instances** in the Cloud Console. + * Apigee Hybrid instances are marked as **Read-only** in the console UI + (configuration changes must be made via Kubernetes/Helm). +2. **API or CLI**: + * Query the organization details (e.g., using `gcloud apigee organizations + describe`). + * Check the `runtimeType` field in the response: + * `CLOUD` indicates a fully managed **Apigee X** organization. + * `HYBRID` indicates an **Apigee Hybrid** deployment. + +## 2. Environments & Environment Groups + +API proxy deployments are scoped to environments, which in turn are routed +through virtual hosts defined in environment groups. + +* **Environments**: A logical partition where API proxies are deployed and + execute. Examples: `dev`, `staging`, `prod`. Policies, Key Value Maps + (KVMs), and Target Servers are scoped to environments. +* **Environment Groups**: A collection of environments grouped under one or + more hostnames. External client traffic is routed to the correct environment + using the hostnames associated with the group and base path configurations. + * *Example*: Hostname `api.cymbal.com` in Environment Group `prod-group` + maps to the `prod` environment. + * *Note*: Virtual hosts in Apigee X utilize a GCP HTTPS Load Balancer + configured in the customer's project, which routes traffic through + Private Service Connect (PSC) or VPC Peering to the Apigee runtime. + +## 3. API Proxies + +An API Proxy is a set of configuration files and policies that act as a facade +for a backend service. It consists of two primary endpoints: + +* **ProxyEndpoint**: Defines the public-facing interface of the proxy, + including: + * `BasePath`: The URI fragment clients target (e.g., `/v1/weather`). + * `Flows`: Pipelines (Preflow, Conditional Flows, Postflow) executing + policies on requests and responses. + * `RouteRule`: Routing logic deciding which TargetEndpoint to invoke based + on headers or query parameters. +* **TargetEndpoint**: Defines how Apigee communicates with the backend service + (target URL, TLS settings, load balancing, target preflow/postflow + execution). + +``` + Client ==[HTTP]==> ProxyEndpoint (Preflow/Postflow) ==[RouteRule]==> TargetEndpoint ==[HTTP]==> Backend Target +``` + +* **Revisions**: Proxies are version-controlled via **Revisions** (e.g., + Revision 1, Revision 2). Revisions are immutable once deployed. Modifying a + proxy creates a new revision, allowing safe blue-green deployments and + rollbacks. + +## 4. API Products + +An API Product is a logical bundle of API resources (proxies and paths) combined +with access rules. + +* API Products are the primary unit of monetization and access control. They + specify: + * Which API proxies and paths are accessible (e.g., Proxy `weather`, Path + `/forecast` only). + * **Quota**: Rate limits enforced on the app (e.g., 1000 calls per month). + * **Key Approval**: Automatic approval or manual review when a developer + requests access. + * **Scopes**: OAuth scopes permitted by this product (e.g., + `read:weather`). + +## 5. Developers & Developer Apps + +To consume an API Product, clients must register and obtain credentials. + +* **Developers**: A profile representing the API consumer (name, email, + company). +* **Developer Apps**: A logical application registered by a Developer that is + associated with one or more API Products. + * When a Developer App is created, Apigee automatically generates a + **Consumer Key** (API Key) and a **Consumer Secret**. + * The Consumer Key must be provided by client requests (via query + parameter, header, or OAuth flow) to identify the application and verify + it is authorized for the associated API Product. diff --git a/skills/cloud/apigee_basics/references/iac-usage.md b/skills/cloud/apigee_basics/references/iac-usage.md new file mode 100644 index 0000000000..ad61da03c1 --- /dev/null +++ b/skills/cloud/apigee_basics/references/iac-usage.md @@ -0,0 +1,139 @@ +# Apigee Infrastructure as Code (Terraform) + +You can automate the deployment of Apigee proxies, products, developers, and +apps using the Google Cloud Terraform Provider. + +> [!NOTE] Terraform is supported for provisioning and managing Apigee resources. +> For a complete overview, see the +> [Google Cloud Terraform Overview](https://docs.cloud.google.com/apigee/docs/api-platform/get-started/terraform-overview). +> This document serves as a reference configuration for automating a basic +> developer setup (proxies, products, developers, and apps) and requires the +> Terraform CLI and appropriate GCP permissions to execute. + +This document outlines the primary resources and provides a comprehensive +configuration example. We assume that the **Apigee Organization** and +**Environment** are already provisioned. + +-------------------------------------------------------------------------------- + +## 1. Primary Terraform Resources + +* **`google_apigee_api_proxy`**: Registers and imports an API Proxy + configuration from a local zipped bundle. +* **`google_apigee_api_product`**: Bundles proxies and resources, exposing + them under specified environments and quotas. +* **`google_apigee_developer`**: Registers developers within the Apigee + identity database. +* **`google_apigee_developer_app`**: Registers application profiles, binding + developers to products, and triggers credential generation. + +-------------------------------------------------------------------------------- + +## 2. Configuration Example + +The following Terraform configuration imports a hello-world proxy zip bundle, +creates an API Product allowing access to it in the `prod` environment, +registers a developer, and creates a developer app to generate the consumer API +key. + +```hcl +# Configure variables +variable "gcp_project" { + type = string + description = "The GCP Project ID" + default = "my-apigee-project" +} + +variable "apigee_org_id" { + type = string + description = "The Apigee Organization ID (usually matches project ID)" + default = "my-apigee-project" +} + +variable "apigee_env_name" { + type = string + description = "The Apigee Environment to deploy to" + default = "prod" +} + +# 1. Import the API Proxy from a local ZIP bundle +# Ensure `helloworld-proxy.zip` is generated and contains the standard `apiproxy` directory. +resource "google_apigee_api_proxy" "helloworld" { + org_id = var.apigee_org_id + name = "helloworld" + config_bundle = "${path.module}/helloworld-proxy.zip" +} + +# 2. Create the API Product bundling the helloworld proxy +resource "google_apigee_api_product" "internal_services" { + org_id = var.apigee_org_id + name = "InternalServicesProduct" + display_name = "Internal Services Product" + description = "API Product to access helloworld services in prod." + + approval_type = "auto" + environments = [var.apigee_env_name] + + # Link the imported proxy + proxies = [google_apigee_api_proxy.helloworld.name] + + # Set usage limits (Quota: 500 calls every 5 minutes) + quota = "500" + quota_type = "calendar" + interval = "5" + time_unit = "minute" + + attributes = { + access = "public" + } +} + +# 3. Register a Developer +resource "google_apigee_developer" "alice" { + org_id = var.apigee_org_id + email = "alice@example.com" + first_name = "Alice" + last_name = "Smith" + user_name = "asmith" +} + +# 4. Create a Developer App associated with the Developer and Product +# This resource generates the client credentials (Consumer Key). +resource "google_apigee_developer_app" "alice_mobile_app" { + org_id = var.apigee_org_id + developer_email = google_apigee_developer.alice.email + name = "AliceMobileApp" + callback_url = "https://example.com/callback" + + # Bind the developer app to the API Product + api_products = [google_apigee_api_product.internal_services.name] +} + +# 5. Output the generated Consumer Key (API Key) +output "alice_api_key" { + value = google_apigee_developer_app.alice_mobile_app.client_id + description = "Alice's generated API Key. Supply this in query parameter or header to access helloworld API." + sensitive = true +} +``` + +### Steps to Run + +**1. Package your local proxy configuration into `helloworld-proxy.zip`** + +```bash +zip -r helloworld-proxy.zip apiproxy/ +``` + +**2. Initialize and apply the configuration using Terraform CLI** + +```bash +terraform init +terraform apply -var="gcp_project=$PROJECT_ID" -var="apigee_org_id=$PROJECT_ID" +``` + +**3. Fetch the generated sensitive key** + +```bash +terraform output -raw alice_api_key +``` diff --git a/skills/cloud/apigee_basics/references/iam-security.md b/skills/cloud/apigee_basics/references/iam-security.md new file mode 100644 index 0000000000..d91c595309 --- /dev/null +++ b/skills/cloud/apigee_basics/references/iam-security.md @@ -0,0 +1,120 @@ +# Apigee IAM & Security Policies + +Securing an API involves both control plane access (who can configure proxies) +and data plane enforcement (how proxy traffic is protected). This document +details standard IAM roles and runtime security policies in Apigee. + +-------------------------------------------------------------------------------- + +## 1. Control Plane: IAM Roles + +GCP IAM controls access to Apigee management resources. The following predefined +roles are standard: + +* **Apigee Admin (`roles/apigee.admin`)**: + * Full access to create, edit, and delete all resources (proxies, + products, environments, keystores, service accounts). + * Assign this to DevOps engineers, administrators, and deployment service + accounts. +* **Apigee API Creator (`roles/apigee.apiCreator`)**: + * Permissions to create and import API proxies. Cannot create environment + groups, environments, or deploy proxies to environment-level resources. + * Assign to standard API developers. +* **Apigee Deployer (`roles/apigee.deployer`)**: + * Permission to deploy and undeploy API proxy revisions to environments. + * Assign to CI/CD pipelines and operations engineers. +* **Apigee Developer (`roles/apigee.developer`)**: + * Permissions to read proxies, products, and manage developers and + developer apps. + * Ideal for portal administrators managing app credentials. + +-------------------------------------------------------------------------------- + +## 2. Data Plane: Security Policies + +API proxies use specialized **Policies** (XML configurations) to secure runtime +traffic. + +### A. API Key Verification (`VerifyAPIKey`) + +The most common way to authenticate client apps. The policy verifies that a +supplied key is valid and registered for the API Product being accessed. + +**Policy Configuration (`VerifyAPIKey-HelloWorld.xml`)**: + +```xml + + + Verify API Key - HelloWorld + + + +``` + +**Flow Placement**: Always place this step in the **ProxyEndpoint PreFlow** to +block unauthorized calls immediately: + +```xml + + + + + VerifyAPIKey-HelloWorld + + + + + +``` + +-------------------------------------------------------------------------------- + +### B. Spike Arrest (`SpikeArrest`) + +Spike Arrest protects backend target servers from sudden traffic spikes, denial +of service (DoS) attacks, or malfunctioning client code. + +**Policy Configuration (`SpikeArrest-10ps.xml`)**: + +```xml + + + Spike Arrest - 10ps + + 10ps + +``` + +* *Note*: Spike Arrest operates on a sliding window. A rate of `10ps` means + Apigee permits one request roughly every 100 milliseconds. Requests + exceeding this micro-interval are immediately blocked with a `429 Too Many + Requests` error. + +**Flow Placement**: Place at the very beginning of the **ProxyEndpoint PreFlow** +(even before authentication) to drop excessive traffic before consuming gateway +CPU resources. + +-------------------------------------------------------------------------------- + +### C. OAuth v2.0 Access Token Verification (`OAuthV2`) + +Used to verify OAuth 2.0 Bearer tokens supplied in the `Authorization` header. + +**Policy Configuration (`VerifyAccessToken.xml`)**: + +```xml + + + Verify Access Token + VerifyAccessToken + +``` + +* *Note on Optional Scopes*: By default, omitting the `` element + verifies the token validity only (Authentication-only). To enforce + fine-grained authorization, you can add the `` element under the + operation (e.g., `read:products`). + +**Flow Placement**: Place in the **ProxyEndpoint PreFlow** prior to routing. +Once verified, details about the authenticated application and developer are +exposed in context variables (e.g., `developer.app.name`, `developer.email`). diff --git a/skills/cloud/apigee_basics/references/mcp-in-apigee.md b/skills/cloud/apigee_basics/references/mcp-in-apigee.md new file mode 100644 index 0000000000..cd4452cd8b --- /dev/null +++ b/skills/cloud/apigee_basics/references/mcp-in-apigee.md @@ -0,0 +1,173 @@ +# Model Context Protocol (MCP) in Apigee + +Apigee allows you to expose your existing REST APIs as **Model Context Protocol +(MCP) tools** to agentic AI applications. Instead of hand-authoring local MCP +servers or complex integrations, Apigee X provides a managed, cloud-native L7 +bridge that handles JSON-RPC translation, security, and discovery automatically. + +-------------------------------------------------------------------------------- + +## 1. Core Concepts + +When you enable MCP in Apigee: * An Apigee proxy acts as the **HTTP MCP Server** +endpoint for compliant MCP hosts/clients. * The proxy translates standard MCP +JSON-RPC methods (like `tools/list` and `tools/call`) into backend REST calls, +maps OpenAPI operations to individual MCP tools, and transcodes the responses. * +A tenant-level managed endpoint (`{ORG_NAME}.mcp.apigee.internal`) is deployed +to execute routing. + +-------------------------------------------------------------------------------- + +## 2. Exposing APIs as MCP Tools: Step-by-Step + +Exposing REST APIs as MCP tools involves creating an OpenAPI spec, provisioning +an **MCP Discovery Proxy**, securing it, and deploying it. + +### Step 1: Create an OpenAPI 3.0.x Specification + +You must define the REST operations you want to expose as MCP tools. * Supported +OpenAPI versions: 3.0.0, 3.0.1, 3.0.2, 3.0.3. * **CRITICAL Hostname Matching +Requirement**: The hostname in the `servers.url` field of the OpenAPI spec +**MUST** exactly match the virtual host **hostname** of the environment group +where you deploy the proxy. + +```yaml +# oas/quickstart-openapi.yaml +--- +openapi: 3.0.3 +info: + title: Cymbal Products API + description: Official API for managing products, mapped to MCP tools. + version: 1.0.0 +servers: + - url: https://api.cymbal.com # MUST match environment group hostname +paths: + /products: + get: + description: Returns a list of available products + operationId: listProducts + responses: + "200": + description: Success +``` + +### Step 2: Create the MCP Discovery Proxy + +1. Open the **Apigee Console**. +2. Navigate to **API proxies** and click **+ Create**. +3. In the **Proxy template** box, select **MCP Discovery Proxy**. +4. Enter a Proxy Name, and upload the `quickstart-openapi.yaml` file. +5. Click **Create**. (This provisions the target endpoint mapping to + `{ORG_NAME}.mcp.apigee.internal`). + +### Step 3: Add a Security Policy + +We strongly recommend securing the MCP endpoint. Add an access token +verification policy at the beginning of the **ProxyEndpoint PreFlow**: 1. In the +proxy editor, click **Develop** -> **Proxy endpoints** -> **default** -> +**PreFlow**. 2. Add a new **OAuth v2.0** policy named `VerifyAccessToken`. 3. +Ensure it executes the `VerifyAccessToken` task. + +### Step 4: Deploy to a Comprehensive Environment + +1. Click **Deploy** in the proxy editor. +2. Select your environment (Note: the environment must be a **Comprehensive** + type, not Lite). +3. Provide a deployment Service Account with `roles/apigee.admin` or + `roles/apigee.deployer` permissions. +4. Click **Deploy**. The status will change from *Provisioning* to *Deployed*. + +### Step 5: Discovery in API Hub + +Deploys are automatically ingested into **API Hub**: 1. Go to the **API Hub** +page in the console. 2. Filter the list by **Style: MCP**. Your proxy appears +here, with API operations automatically mapped to discoverable MCP tools. + +-------------------------------------------------------------------------------- + +## 3. Interacting with the MCP Endpoint + +Compliance clients can interact with your endpoint at +`https://{ENVIRONMENT_GROUP_HOSTNAME}/mcp` using standard HTTP POST JSON-RPC +payloads. + +### A. Initialize the Server + +Clients negotiate the protocol version using the `initialize` method: + +**Request** + +```bash +curl -X POST "https://api.cymbal.com/mcp" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer YOUR_OAUTH_TOKEN" \ + -d '{ + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": { + "protocolVersion": "2025-11-25" + } + }' +``` + +**Response** + +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "capabilities": { + "tools": { + "listChanged": false + } + }, + "protocolVersion": "2025-11-25", + "serverInfo": { + "name": "api.cymbal.com", + "version": "1.0.0" + } + } +} +``` + +### B. List Tools + +Retrieve the list of available tools matching the API operations: + +**Request** + +```bash +curl -X POST "https://api.cymbal.com/mcp" \ + -H "Content-Type: application/json" \ + -H "MCP-Protocol-Version: 2025-11-25" \ + -H "Authorization: Bearer YOUR_OAUTH_TOKEN" \ + -d '{ + "jsonrpc": "2.0", + "id": 2, + "method": "tools/list", + "params": {} + }' +``` + +**Response** + +```json +{ + "id": 2, + "jsonrpc": "2.0", + "result": { + "tools": [ + { + "name": "listProducts", + "description": "Returns a list of available products", + "inputSchema": { + "type": "object", + "properties": {} + } + } + ] + } +} +``` diff --git a/skills/cloud/apigee_basics/references/proxy-bundle-structure.md b/skills/cloud/apigee_basics/references/proxy-bundle-structure.md new file mode 100644 index 0000000000..9f62c5e44d --- /dev/null +++ b/skills/cloud/apigee_basics/references/proxy-bundle-structure.md @@ -0,0 +1,130 @@ +# Apigee API Proxy Bundle Structure + +Apigee API proxies are deployed as zip archives called **API Proxy Bundles**. To +programmatically generate or manually author a valid, deployable API proxy, you +must follow a strict directory structure and use correct XML configuration +files. + +This document details the folder hierarchy, standard XML templates, and +packaging steps for a basic "hello-world" API proxy. + +-------------------------------------------------------------------------------- + +## 1. Directory Hierarchy + +An API Proxy Bundle must have `apiproxy` as its root folder. The standard +structure is: + +```text +apiproxy/ +├── helloworld.xml # Base Configuration (must match name attribute & folder parent) +├── proxies/ +│ └── default.xml # ProxyEndpoint Configuration (defines ingress & routing) +└── targets/ + └── default.xml # TargetEndpoint Configuration (defines egress target URL) +``` + +* **Optional Folders**: + * `apiproxy/policies/`: XML policy configuration files (e.g., + `VerifyAPIKey.xml`, `SpikeArrest.xml`). + * `apiproxy/resources/`: Contains custom scripts (e.g., `jsc/` for + JavaScript, `py/` for Python, `java/` for custom JARs). + +-------------------------------------------------------------------------------- + +## 2. Base XML Templates + +Below are the exact XML configurations required to build a valid, deployable +hello-world API proxy named `helloworld` routing to +`https://mocktarget.apigee.net`. + +### A. Base Configuration: `apiproxy/helloworld.xml` + +This defines the proxy name and references all proxy and target endpoints. The +filename **must** match the `` attribute. + +```xml + + + + Hello World API Proxy facade routing to Mock Target + helloworld + + default + + + default + + +``` + +### B. ProxyEndpoint: `apiproxy/proxies/default.xml` + +Defines the client-facing ingress interface and routing rules. * `` +specifies the URI fragment clients target (e.g. `/helloworld`). * `` +maps the request to a named target endpoint (in this case, `default`). + +```xml + + + Default Proxy Endpoint + + + + + + + + + + + /helloworld + + + default + + +``` + +### C. TargetEndpoint: `apiproxy/targets/default.xml` + +Defines the backend-facing egress interface and target connection URL. * `` +specifies the destination backend address. + +```xml + + + Default Target Endpoint + + + + + + + + + + + https://mocktarget.apigee.net + + +``` + +-------------------------------------------------------------------------------- + +## 3. Packaging the Bundle + +To package these files into a deployable zip archive, navigate to the parent +directory containing the `apiproxy` folder and run the standard `zip` utility: + +```bash +zip -r helloworld.zip apiproxy/ +``` + +* **Important Packaging Rules**: + * The `apiproxy` folder must be at the root of the zip archive. Do not zip + the outer parent folder (e.g., zipping `my-project/apiproxy` from + outside will cause deployment errors; you must be inside `my-project` + and run `zip -r helloworld.zip apiproxy/`). + * Ensure there are no hidden folders (like `.git`) included inside the + `apiproxy/` directories.