<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Adarsh Pandey on Medium]]></title>
        <description><![CDATA[Stories by Adarsh Pandey on Medium]]></description>
        <link>https://medium.com/@adarshpandey022?source=rss-d38721a4bc98------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*bLjlBhd9lzKYog24KyB31g.jpeg</url>
            <title>Stories by Adarsh Pandey on Medium</title>
            <link>https://medium.com/@adarshpandey022?source=rss-d38721a4bc98------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 30 May 2026 17:39:46 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@adarshpandey022/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[GCP: Migrate Cloud SQL b/w Projects]]></title>
            <link>https://medium.com/@adarshpandey022/gcp-migrate-cloud-sql-b-w-projects-8ccbe04a6e2f?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/8ccbe04a6e2f</guid>
            <category><![CDATA[cloud-sql]]></category>
            <category><![CDATA[sql-migration]]></category>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[automation-solution]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Fri, 11 Oct 2024 22:15:19 GMT</pubDate>
            <atom:updated>2026-04-25T11:16:49.149Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ZvchThQscXIg_zbY" /></figure><h3>Introduction</h3><p>There are countless enterprise scenarios where you might need to perfectly clone a Google Cloud SQL instance between entirely separate GCP projects. Whether you are bootstrapping a mirrored environment for staging, executing disaster recovery drills, or securely isolating client data into dedicated project boundaries, cross-project database migration is a fundamental Cloud Engineering capability.</p><p>While Google Cloud does not currently support direct “one-click” instance cloning across isolated project boundaries, you can achieve the exact same pristine result through a highly deterministic two-step maneuver: aggressively capturing a backup from the source instance and meticulously restoring it into an identically provisioned target instance within the destination project.</p><h3>The Challenge: Navigating Cross-Project Boundaries</h3><p>The core challenge lies in GCP’s rigid Identity and Access Management (IAM) perimeter. Cloud SQL backups are fundamentally tied to the lifecycle of their source instance and project. You cannot simply point a new instance in a different project at a bucket containing a database dump without carefully choreographing permissions and API calls.</p><p>Furthermore, minimizing downtime during this process requires executing these operations swiftly, often through automation, to ensure the destination database perfectly matches the state of the source at the time of the cutover.</p><p>Common Pitfall: Many engineers attempt to execute a `pg_dump` or `mysqldump` and pipe it over the network to the new project. For multi-terabyte databases, this approach is catastrophically slow, prone to network interruptions, and locks tables for unacceptable durations.</p><p>[Insert Image: High-level architecture diagram illustrating the IAM boundaries between Project A (Source) and Project B (Target), highlighting the cross-project Cloud SQL Admin API interaction.]</p><h3>The Solution/Process: The Native Restoration Strategy</h3><p>This native guide will walk you through exactly how to bypass network-bound dumps and perform a rapid block-level clone of Cloud SQL instances across projects using the Google Cloud CLI (gcloud) and heavily restricted Service Accounts.</p><h3>Phase 1: Secure the Source Cloud SQL Backup</h3><p>Because cross-project cloning isn’t a native one-click feature, the very first step is safely triggering a point-in-time snapshot backup from the source.</p><pre>gcloud sql backups create --instance=[SOURCE_INSTANCE] --project=[SOURCE_PROJECT]</pre><p>Once completed, query the backup registry to retrieve the immutable ID of the backup that was just generated for restoration:</p><pre>gcloud sql backups list --instance=[SOURCE_INSTANCE] --project=[SOURCE_PROJECT]</pre><p>Pro-Tip: Never use a scheduled automated backup ID for a live migration cutover. Always manually execute a fresh create command to ensure your target database reflects the absolute latest transaction state before you route traffic to it.</p><h3>Phase 2: Provision the Target Cloud SQL Instance</h3><p>Before restoring the backup payload, you need a structurally identical target Cloud SQL instance provisioned in the destination project to receive the restoration data block.</p><pre>gcloud sql instances create [TARGET_INSTANCE] \<br>    --database-version=[SOURCE_INSTANCE_DATABASE_VERSION] \<br>    --cpu=2 --memory=8GiB --region=us-west1 \<br>    --root-password=[PASSWORD] \<br>    --project=[TARGET_PROJECT]</pre><p>CRITICAL: Make sure that the database version (e.g., POSTGRES_14) exactly matches that of the source instance! The restoration will hard-fail otherwise.</p><h3>Phase 3: Cross-Project IAM Configuration</h3><p>To automate this cross-boundary data transfer, you must use a dedicated Service Account (SA). The SA will physically live in the Target project but requires specific viewing grants in the Source project.</p><p>1. Create the Service Account in the TARGET_PROJECT:</p><pre>gcloud iam service-accounts create [SERVICE_ACCOUNT] --project=[TARGET_PROJECT]</pre><p>2. Grant Viewer permissions in the SOURCE_PROJECT so the target SA can see and read the source backup:</p><pre>gcloud projects add-iam-policy-binding [SOURCE_PROJECT] \<br>   --member=&quot;serviceAccount:[SERVICE_ACCOUNT]@[TARGET_PROJECT].iam.gserviceaccount.com&quot; \<br>   --role=&quot;roles/cloudsql.viewer&quot;</pre><p>3. Grant Cloud SQL Admin permissions in the TARGET_PROJECT so it has the authorization to aggressively overwrite the new instance with the payload data:</p><pre>gcloud projects add-iam-policy-binding [TARGET_PROJECT] \<br>   --member=&quot;serviceAccount:[SERVICE_ACCOUNT]@[TARGET_PROJECT].iam.gserviceaccount.com&quot; \<br>   --role=&quot;roles/cloudsql.admin&quot;</pre><h3>Phase 4: Executing the Cross-Project Restore</h3><p>Now, you will orchestrate the backup restoration from the source project directly into the target project’s instance. As this currently lacks a single unified gcloud flag, we interact directly with the Cloud SQL Admin REST API using the authenticated SA token.</p><pre>curl -X POST \<br> -H &quot;Authorization: Bearer $(gcloud auth print-access-token)&quot; \<br> -H &quot;Content-Type: application/json&quot; \<br> &quot;https://sqladmin.googleapis.com/v1/projects/[TARGET_PROJECT]/instances/[TARGET_INSTANCE]/restoreBackup&quot; \<br> --data-raw &#39;{<br>   &quot;restoreBackupContext&quot;: {<br>     &quot;backupRunId&quot;: [SOURCE_BACKUP_ID],<br>     &quot;project&quot;: &quot;[SOURCE_PROJECT]&quot;,<br>     &quot;instanceId&quot;: &quot;[SOURCE_INSTANCE]&quot;<br>   }<br> }&#39;</pre><p>[Insert Image: A sequential diagram visualizing the REST API call flow: Authenticating as the SA, hitting the restoreBackup endpoint, and the GCP internal plane migrating the data.]</p><h3>Key Takeaways</h3><ul><li>Native instance cloning across projects is impossible; the process relies on a backup from Project A restored into Project B.</li><li>Avoid traditional logical dumps (like pg_dump) for large migrations due to network latency and excessive downtime.</li><li>The Target Instance must be provisioned with the exact equivalent Database Version as the Source Instance.</li><li>Strict IAM choreography is required: A Service Account in the target project needs cross-project Cloud SQL Viewer permissions to read the source data payload.</li></ul><h3>Conclusion</h3><p>By leveraging GCP’s native Cloud SQL Backup and Restore API, combined with precise Cross-Project IAM bindings, you can rapidly and securely clone massive databases across strict project boundaries. Whether executed manually for a one-off migration or baked into a robust automated bash script for CI/CD pipeline disaster recovery drills, this architecture guarantees zero data loss and significantly dramatically reduces database cutover latency.</p><h3>Further Reading</h3><ul><li><a href="https://cloud.google.com/sql/docs/postgres/backup-recovery/restoring#cross-project">GCP Official Docs: Restoring a backup to a different project</a></li><li><a href="https://cloud.google.com/iam/docs/understanding-roles">GCP IAM: Understanding Roles and Service Accounts</a></li><li><a href="https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1/instances/restoreBackup">Cloud SQL Admin ReST API Reference</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8ccbe04a6e2f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GCP: Receive Alerts on Google Chat for Resource Creation / Deletion]]></title>
            <link>https://medium.com/@adarshpandey022/gcp-receive-alerts-on-google-chat-for-new-resource-creation-5e45b9f16500?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/5e45b9f16500</guid>
            <category><![CDATA[google-chat]]></category>
            <category><![CDATA[monitoring]]></category>
            <category><![CDATA[google-cloud]]></category>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[alerting-mechanism]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Thu, 03 Oct 2024 20:26:44 GMT</pubDate>
            <atom:updated>2026-04-25T11:19:50.749Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nmG6Ejk-4j8gmk0G" /></figure><h3>Introduction</h3><p>Google Cloud Platform (GCP) provides an enormous suite of services designed to monitor and manage vast fleets of cloud infrastructure efficiently. However, as cloud footprints expand across decentralized engineering teams, a common and critical enterprise requirement emerges: the need to receive real-time alerts whenever a new resource is provisioned or deleted within your project.</p><p>In this practical engineering guide, we will walk through architecting a modern, event-driven GCP Cloud Function pipeline designed to instantly push infrastructure alerts directly into a Google Chat space using Cloud Logging sinks and Pub/Sub.</p><h3>The Challenge: Sprawl and Shadow IT</h3><p>Without automated visibility into infrastructure lifecycle events, organizations quickly fall victim to “cloud sprawl” and Shadow IT. Developers might spin up expensive, oversized Compute Engine instances for testing and forget to terminate them, leading to ballooning monthly billing surprises. Worse, unauthorized deletion of critical Cloud Storage buckets or Cloud Run services can cause catastrophic, silent production outages if the operations team isn’t immediately notified.</p><p>Common Pitfall: Relying solely on daily billing exports or manual console audits to track newly created resources. By the time a billing report flags a massive GPU instance, it has already been running for 24 hours. Real-time logging is the only acceptable defense.</p><h3>The Solution/Process: Event-Driven Alerting Pipeline</h3><p>This solution relies on intercepting Google Cloud Audit Logs in real-time. We will set up a log filter, route matching logs securely to a Pub/Sub topic, and trigger a Serverless Cloud Function that instantly fans out parsed notifications to Google Chat.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/1*2_Li0MCShOffYjqWOZzitA.png" /></figure><h3>Prerequisites</h3><ul><li>A GCP Project with Logging Admin, Cloud Function Admin, and Pub/Sub Admin IAM roles assigned to your user account.</li><li>A dedicated Google Chat Space where you want to route the incoming alerts.</li></ul><h3>Step 1: Configure a Google Chat Webhook URL</h3><p>First, set up a custom inbound webhook in your target Google Chat Space:</p><ol><li>Click on the Dropdown Menu next to the Space name &gt; Space Settings &gt; Manage Webhooks.</li><li>Create a new webhook (named “GCP Resource Alerts”) and copy the provided Webhook URL.</li></ol><p>Pro-Tip: Treat this Webhook URL like a highly sensitive production password. If leaked, anyone on the internet can POST arbitrary malicious messages into your corporate chat space. We will secure it using Environment Variables.</p><h3>Step 2: Route Audit Logs to a Pub/Sub Topic</h3><p>Configure a Log Sink to strictly intercept specific Google Cloud Admin Activity logs and export them to a Pub/Sub topic:</p><ol><li>Navigate to Logging &gt; Logs Router in the GCP Console and click Create Sink.</li><li>Name the Sink new_resource_lifecycle_sink.</li><li>Choose Cloud Pub/Sub topic as the Sink Destination and create a new topic named resource-alerts-topic.</li></ol><p>Provide the following advanced inclusion filter to elegantly capture Compute, Cloud Run, Cloud SQL, and Cloud Functions resource lifecycle events while aggressively ignoring noise:</p><pre>protoPayload.@type=&quot;type.googleapis.com/google.cloud.audit.AuditLog&quot; AND NOT protoPayload.authenticationInfo.principalEmail:(&quot;gserviceaccount.com&quot;)<br>( protoPayload.methodName=&quot;v1.compute.instances.insert&quot; AND protoPayload.authorizationInfo.permission=&quot;compute.instances.create&quot;) OR<br>( protoPayload.methodName=&quot;google.cloud.run.v1.Services.CreateService&quot; AND protoPayload.authorizationInfo.permission=&quot;run.services.create&quot;) OR<br>( protoPayload.methodName=&quot;cloudsql.instances.create&quot; AND operation.first=&quot;true&quot;) OR<br>( protoPayload.methodName=&quot;v1.compute.instances.delete&quot;  AND protoPayload.authorizationInfo.permission=&quot;compute.instances.delete&quot; ) OR<br>( protoPayload.methodName:&quot;cloudsql.instances.delete&quot; AND operation.first=&quot;true&quot;)</pre><p><em>Note: We deliberately exclude logs triggered by automated service accounts by filtering out “@gserviceaccount.com” to prevent alert fatigue. Adjust this depending on your CI/CD requirements.</em></p><h3>Step 3: Deploy the Cloud Function Webhook Parser</h3><p>Deploy the “glue” code: a Cloud Function that listens to the Pub/Sub topic, transforms the raw Audit Log JSON into a readable Google Chat Card, and securely POSTs it.</p><ol><li>Navigate to Cloud Functions. Click Create Function.</li><li>Name it chat-alert-parser, select 2nd gen environment, and set the trigger to the resource-alerts-topic Pub/Sub topic.</li><li>Select Python 3.9 (or newer) as the Runtime.</li></ol><p>Security Configuration: Dissect your massive Google Chat Webhook URL into three parts: https://chat.../spaces/{SPACE_ID}/messages?key={KEY}&amp;token={TOKEN}. Add SPACE_ID, KEY, and TOKEN as strictly defined Environment Variables in the function setup.</p><p>Use the following robust Python logic in main.py:</p><pre>import os<br>import base64<br>import json<br>import requests<br>import logging</pre><pre>logging.basicConfig(level=logging.INFO)</pre><pre>GOOGLE_CHAT_SPACE_ID = os.environ.get(&quot;SPACE_ID&quot;)<br>GOOGLE_CHAT_API_KEY = os.environ.get(&quot;KEY&quot;)<br>GOOGLE_CHAT_TOKEN = os.environ.get(&quot;TOKEN&quot;)</pre><pre>DELETE_METHODS = [<br>    &quot;v1.compute.instances.delete&quot;,<br>    &quot;cloudsql.instances.delete&quot;,<br>    &quot;google.cloud.run.v1.Services.DeleteService&quot;,<br>]</pre><pre>def format_chat_message(extracted_data, is_delete):<br>    action_type = &quot;Resource Deleted&quot; if is_delete else &quot;New Resource Created&quot;<br>    color = &quot;#FF0000&quot; if is_delete else &quot;#00FF00&quot;<br>    <br>    return {<br>        &quot;cards_v2&quot;: [{<br>            &quot;card&quot;: {<br>                &quot;header&quot;: { &quot;title&quot;: f&quot;{action_type}&quot; },<br>                &quot;sections&quot;: [{<br>                    &quot;widgets&quot;: [<br>                        {&quot;text_paragraph&quot;: {&quot;text&quot;: f&quot;Principal: {extracted_data.get(&#39;principal&#39;, &#39;Unknown&#39;)}&quot;}},<br>                        {&quot;text_paragraph&quot;: {&quot;text&quot;: f&quot;Resource: {extracted_data.get(&#39;resource_type&#39;, &#39;Unknown&#39;)}&quot;}},<br>                        {&quot;text_paragraph&quot;: {&quot;text&quot;: f&quot;Project ID: {extracted_data.get(&#39;project_id&#39;, &#39;Unknown&#39;)}&quot;}}<br>                    ]<br>                }]<br>            }<br>        }]<br>    }</pre><pre>def send_message(event, context):<br>    try:<br>        message_data = base64.b64decode(event[&#39;data&#39;]).decode(&#39;utf-8&#39;)<br>        payload = json.loads(message_data)</pre><pre>        url = f&quot;https://chat.googleapis.com/v1/spaces/{GOOGLE_CHAT_SPACE_ID}/messages?key={GOOGLE_CHAT_API_KEY}&amp;token={GOOGLE_CHAT_TOKEN}&quot;<br>        <br>        principal = payload.get(&quot;protoPayload&quot;, {}).get(&quot;authenticationInfo&quot;, {}).get(&quot;principalEmail&quot;, &quot;N/A&quot;)<br>        res_type = payload.get(&quot;resource&quot;, {}).get(&quot;type&quot;, &quot;N/A&quot;)<br>        project_id = payload.get(&quot;resource&quot;, {}).get(&quot;labels&quot;, {}).get(&quot;project_id&quot;, &quot;N/A&quot;)<br>        <br>        method_name = payload.get(&#39;protoPayload&#39;, {}).get(&#39;methodName&#39;, &#39;&#39;)<br>        is_delete = method_name in DELETE_METHODS<br>        <br>        extracted_data = {&quot;principal&quot;: principal, &quot;resource_type&quot;: res_type, &quot;project_id&quot;: project_id}<br>        chat_message = format_chat_message(extracted_data, is_delete)<br>        <br>        requests.post(url, headers={&#39;Content-Type&#39;: &#39;application/json&#39;}, json=chat_message)<br>    except Exception as e:<br>        logging.error(f&quot;Function execution failed: {e}&quot;)</pre><p>Define dependencies in requirements.txt:</p><pre>requests==2.31.0</pre><p>Deploy the function.</p><h3>Step 4: Live Testing</h3><p>To empirically test the architecture, manually spin up an inexpensive disposable Compute Engine VM instance. Because the Sink filter captures compute instances, it should immediately populate the Pub/Sub topic, trigger the function, and instantly drop a richly formatted Card natively inside your Google Chat space listing the resource type and culprit user’s email.</p><p>[Insert Image: A screenshot of the Google Chat interface showing the successfully delivered formatted JSON card alert reading “New Resource Created”.]</p><h3>Key Takeaways</h3><ul><li>Real-time Audit Logs: Google Cloud Audit Logs inherently capture every API call. Filtering them strictly at the Router Sink level is the most elegant way to build event triggers without polling.</li><li>Decoupled Architecture: Pub/Sub effectively decouples log generation from log processing. If your Google Chat webhook goes down or rate-limits you, Pub/Sub will safely queue the alerts until the function can successfully process them.</li><li>Security Stance: Placing Chat API tokens inside Cloud Function environment variables prevents accidental inclusion in version control systems (like GitHub).</li></ul><h3>Conclusion</h3><p>By leveraging purely Event-Driven Architectures utilizing Google Cloud Logging Sinks, Pub/Sub, and serverless Cloud Functions, you can effortlessly wire up complex, real-time alert pipelines for essentially any metric or audit log. Setting up intelligent Chat alerts for resource creation and destruction is a hyper-effective and profoundly scalable baseline to guarantee security parity, avoid surprise billing limits, and enforce robust infrastructure governance across your entire organization.</p><h3>Further Reading</h3><ul><li><a href="https://cloud.google.com/logging/docs/routing/overview">GCP Official Docs: Routing and storage overview (Log Sinks)</a></li><li><a href="https://cloud.google.com/pubsub/docs/overview">GCP Official Docs: Cloud Pub/Sub architecture</a></li><li><a href="https://developers.google.com/chat/how-tos/webhooks">Google Workspace Developers: Setting up incoming webhooks for Chat</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5e45b9f16500" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GCP Network Connectivity Center: Embracing the Hub-and-Spoke Topology ]]></title>
            <link>https://medium.com/@adarshpandey022/gcp-network-connectivity-center-embracing-the-hub-and-spoke-topology-b096d9bd775d?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/b096d9bd775d</guid>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[hub-and-spoke]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Fri, 20 Sep 2024 22:43:08 GMT</pubDate>
            <atom:updated>2026-04-25T11:27:12.008Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*alKgDjom48M4RWrs" /></figure><h3>Introduction</h3><p>In today’s aggressively expanding hybrid IT landscape, modern enterprise businesses require seamless, high-bandwidth connectivity between legacy on-premises infrastructure and bleeding-edge cloud resources. While Google Cloud’s traditional Shared VPC network model has been historically instrumental in isolating and managing distinct workloads across separate VPC networks, as your footprint scales globally, pairing VPCs becomes an unwieldy operational nightmare.</p><p>Enter the modern paradigm: the Hub-and-Spoke topology utilizing GCP’s powerhouse solution, the Network Connectivity Center (NCC). This architecture shifts networking away from messy web-like peering into a clean, centralized, and highly governable control plane.</p><h3>The Challenge: The “VPC Peering Spaghetti” Problem</h3><p>Historically, connecting five different VPCs in GCP required building ten separate, reciprocal VPC Network Peering connections. If you scale that to twenty VPCs, you are managing hundreds of independent peering links. This full-mesh architecture rapidly becomes entirely unmanageable, incredibly difficult to audit for security compliance, and strictly limits transitive routing capabilities.</p><p>Common Pitfall: Attempting to route traffic transitively through a middleman VPC. GCP VPC Peering is strictly non-transitive. If VPC A peers with VPC B, and VPC B peers with VPC C, VPC A literally cannot route packets to VPC C naturally. Engineers often waste days attempting to forcefully hack routes around this fundamental cloud limitation.</p><h3>The Solution/Process: Architecture with Network Connectivity Center</h3><p>The Hub-and-Spoke topology is the undisputed best-practice architectural pattern for massive-scale networking. This design centralizes network control routing tables, natively supports transitivity, and grants highly governable access to disparate cloud and on-premises environments.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S44S-yWbd6OF2OwR1ICwXw.png" /><figcaption>Figure 1: Mesh VPC Peering vs Hub-and-Spoke topology using Network Connectivity Center.</figcaption></figure><h3>Understanding Hubs and Spokes</h3><p>The terminology is simple but critically important to mastering this topology:</p><ul><li>The Hub: Acts as the central coordinating brain. A Network Connectivity Center hub is a global management resource to which you persistently attach multiple dynamic spokes. A single global hub can simultaneously route localized spokes originating from multiple different GCP regions worldwide.</li><li>The Spokes: Represent the leaf networks. A spoke is a functional, routing connection linking a VPC network, legacy on-premises network, or SD-WAN hybrid fabric back to the central hub. Spokes autonomously export and dynamically import BGP routes, facilitating true zero-touch connectivity.</li></ul><h3>The Two Primary Spoke Types</h3><h4>1. Google Cloud VPC Spokes</h4><p>VPC spokes natively attach standard GCP Virtual Private Clouds directly to the centralized hub.</p><ul><li>Simplified Connectivity: Radically obliterates the need for complex, unmanageable pair-wise VPC peering structures.</li><li>Route Exchange: VPC spokes inherently enable the seamless, real-time exchange of standard IPv4 and IPv6 routes between entirely isolated VPCs via the central hub’s dynamic routing table.</li><li>Flexibility: Spokes can instantly connect VPCs situated within the identical project, different projects, or remarkably, across completely different GCP organizations.</li></ul><h4>2. Hybrid Spokes (Connecting the Edge)</h4><p>Hybrid spokes are utilized when integrating GCP with your external networks.</p><ul><li>They consist of dedicated Cloud Interconnect VLAN attachments, high-availability (HA) VPN IPsec tunnels, or third-party Router appliance VMs (like Cisco or Fortinet).</li><li>By attaching Hybrid Spokes to the Hub, your distinct VPC networks effectively act as a massive global enterprise Wide Area Network (WAN).</li></ul><p>Pro-Tip: Never place Hybrid Spokes inside a standard “Workload VPC.” Always engineer a dedicated, hardened “Routing VPC” strictly intended to house your Interconnects and VPNs before attaching that specific VPC to the NCC hub. This provides a definitive point of security filtering.</p><h3>Topology Variants: Mesh vs. Star</h3><p>NCC accommodates two distinct architectural shapes depending on your organization’s security posture:</p><h4>The Mesh Topology Variant</h4><p>This is the default stance. It provides intense, high-scale network connectivity synchronously. All spokes can natively, autonomously connect to and route packets to every other attached spoke unconditionally. It is effectively a managed flat network.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hacPmovltDTABtKTbVtrww.png" /><figcaption>Figure 2: Mesh topology — full any-to-any connectivity between all spokes.</figcaption></figure><h4>The Star Topology Variant</h4><p>This is utilized for strict regulatory compliance. Edge spokes and their localized subnets can reach <em>only</em> designated center spokes (often containing shared security services like firewalls). Edge spokes cannot communicate with other Edge spokes. This guarantees strict layer-3 isolation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eQZcdIY1NyPAg48RYg3New.png" /><figcaption>Figure 3: Star topology — edge spokes connect only through the security center spoke.</figcaption></figure><h3>Mesh vs. Star: Choosing the Right Topology</h3><p>Selecting between Mesh and Star topologies depends entirely on your organizational security requirements and the level of trust between different business units.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/876/1*zYj5RrEpiZblV4YFLRNzBg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CDGapwGGXfLHWvtnL13iVQ.png" /><figcaption>Figure 4: Side-by-side comparison — Mesh (any-to-any) vs Star (hub-only) topology.</figcaption></figure><h3>Key Takeaways (And Critical Limitations)</h3><ul><li>VPC Peering Conflicts: You literally cannot utilize standard VPC Network Peering between two VPCs that are simultaneously attached as spokes to the identical NCC hub.</li><li>Dynamic Routing Requirement: Manual exchange of static IPv4 routes across VPC spokes is not supported. NCC relies entirely on automated dynamic BGP routing updates.</li><li>Overlapping Subnets: If two spokes contain overlapping CIDR IP ranges, you must strictly implement manual route export filters to prevent catastrophic BGP route hijacking.</li></ul><h3>Conclusion</h3><p>The Hub-and-Spoke topology formalized in Google Cloud’s Network Connectivity Center offers an extraordinarily scalable and fiercely manageable enterprise networking architecture. By abandoning legacy VPC Peering and centralizing core network route propagation, organizations can securely connect fragmented cloud footprints and sprawling on-premises environments, radically simplifying their global hybrid multi-cloud connectivity stance forever.</p><h3>Further Reading</h3><ul><li><a href="https://cloud.google.com/network-connectivity/docs/network-connectivity-center/concepts/overview">GCP Official Docs: Network Connectivity Center Overview</a></li><li><a href="https://cloud.google.com/architecture/hub-and-spoke-network-architecture">GCP Cloud Architecture Center: Hub-and-spoke network architecture</a></li><li><a href="https://cloud.google.com/vpc/docs/vpc-peering">GCP Official Docs: VPC Network Peering (And its Limitations)</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b096d9bd775d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Automating Cloud SQL Manual Backup Deletion in GCP]]></title>
            <link>https://medium.com/@adarshpandey022/automating-cloud-sql-manual-backup-deletion-in-gcp-3a357a2eac8d?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/3a357a2eac8d</guid>
            <category><![CDATA[cloud-sql]]></category>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[backup]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Thu, 19 Sep 2024 18:16:10 GMT</pubDate>
            <atom:updated>2026-04-25T11:28:45.698Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JkZzx6HywVLdSGXf" /></figure><h3>Introduction</h3><p>Cloud SQL backups are absolutely essential for ensuring the high availability and strict integrity of your mission-critical data in Google Cloud Platform (GCP). While GCP natively and automatically manages the deletion of rolling “scheduled” daily backups, on-demand manual backups behave entirely differently. Manual backups are never swept by GCP; they persist indefinitely and require users to delete them manually.</p><p>In standard GCP environments, you cannot natively specify an exact chronological time (e.g., exactly 2:00 AM) to trigger a scheduled backup. The closest option is arbitrarily defining a vague 4-hour window during which GCP will randomly perform the automated backup. If your strict regulatory requirement is to enforce a backup at a highly specific time concurrently across services, you absolutely must opt for orchestrating manual backups via external triggers like Cloud Scheduler.</p><h3>The Challenge: The Cost of Manual Backups</h3><p>While orchestrating manual backups solves the strict scheduling problem, it introduces a dangerous new challenge. Manually tracking and forcefully deleting these accumulated manual backups becomes operationally tedious and overwhelmingly expensive, especially if you manage multiple highly-active Cloud SQL instances.</p><p>Manual backups quietly accumulate exponentially over time, leading to shocking unmanaged storage cost spikes on your GCP billing. Allowing humans to manually clear these out introduces significant Risk Mitigation issues, such as an engineer accidentally deleting yesterday’s critical backup.</p><p>Common Pitfall: Many engineering teams set up automated manual backups via Cloud Scheduler or Cloud Functions but forget to implement the lifecycle management cleanup, resulting in thousands of dollars of wasted GCS bucket storage over a few months.</p><p>[Insert Image: A cost-graph diagram showing the exponential growth of Cloud Storage costs when manual SQL backups are left unmanaged over 6 months.]</p><h3>The Solution/Process: Automated Shell Exorcism</h3><p>In this technical guide, I will walk you through completely automating the aggressive deletion of stale manual Cloud SQL backups using a robust, easily deployable shell script. This automated script queries all your Cloud SQL backups, rigorously compares their timestamps against a user-defined retention policy, and surgically deletes backups that exceed that strict TTL (Time to Live) period.</p><h3>The Automation Script Breakdown</h3><p>Let’s walk precisely through the core operational components of the script and how it confidently automates the tedious process of destroying old Cloud SQL manual backups.</p><h4>1. Dynamic User Input:</h4><p>The script initializes by securely prompting the executing user or CI runner for three required inputs: the SQL Instance Name, Project ID, and the Retention Period in days.</p><pre>echo &quot;Enter Instance Name: &quot;<br>read INSTANCE<br>echo &quot;Enter Project ID: &quot;<br>read PROJECT<br>echo &quot;Enter Retention period in Days: &quot;<br>read DAY</pre><h4>2. Timestamp Calculation &amp; Retention Math:</h4><p>The script calculates the exact current system time in seconds (UNIX epoch timestamp) and algebraically computes the total retention period translated into raw seconds based on the user’s input.</p><pre>current_timestamp=$(date +%s)<br>retention_period=$(($DAY * 24 * 60 * 60))</pre><h4>3. Querying the Backup API &amp; Deletion Sweep:</h4><p>The script deeply fetches the entire backup registry using the gcloud sql backups list command. It strictly formats the output into a parseable CSV containing the exact Backup ID, the UTC start time, and the execution status. Using a while loop, it evaluates the TTL differences and gracefully issues the delete command.</p><pre>while IFS=&#39;,&#39; read -r id input_date status; do<br>  if [[ &quot;$status&quot; != &quot;status&quot; &amp;&amp; &quot;$status&quot; == &quot;SUCCESSFUL&quot; ]]; then<br>    input_timestamp=$(convert_to_timestamp &quot;$input_date&quot;)<br>    difference=$((current_timestamp - input_timestamp))<br>    if ((difference &gt; retention_period)); then<br>      echo &quot;Deleting stale $id backup created at $input_date (Instance: $INSTANCE)&quot;<br>      echo Y | gcloud sql backups delete &quot;$id&quot; --project &quot;$PROJECT&quot; --instance=&quot;$INSTANCE&quot;<br>    fi<br>  fi<br>done &lt; &quot;$input_csv&quot;</pre><p>Pro-Tip: To maintain a provable paper trail, the script logs the exact state of the backup array globally <em>both before and completely after</em> the destructive loops into a local CSV file. This guarantees a verifiable audit trail proving that the TTL enforcement functioned identically as configured for compliance audits.</p><p>[Insert Image: High-level architectural flowchart showing Cloud Scheduler triggering a pipeline running the bash script, hitting the Cloud SQL Admin API, and outputting the CSV audit log.]</p><h3>Key Takeaways</h3><ul><li>GCP’s automated scheduled backups do not support precise chronological timing; manual backups orchestrated externally are required for strict regulatory constraints.</li><li>Manual backups are never automatically deleted by GCP, posing a severe cost and compliance risk if left unmanaged.</li><li>You can aggressively automate the deletion of these backups by combining the gcloud CLI tools with basic chronological epoch math in a bash script.</li><li>Always generate an audit log (like a CSV) before and after programmatic destructive actions to satisfy compliance and simplify incident debugging.</li></ul><h3>Conclusion</h3><p>Aggressively automating the deletion pipeline of manual Cloud SQL backups guarantees that old, stale disaster recovery snapshots do not silently clutter your GCP projects and brutally inflate your cloud storage utilization costs. By scheduling this heavily deterministic shell tool simply via a basic CronJob, Cloud Build pipeline, or GitLab CI schedule, you can effectively enforce rigorous global data retention policies while simultaneously retaining total visibility output logs for deep auditing purposes.</p><h3>Further Reading</h3><ul><li><a href="https://cloud.google.com/sql/docs/mysql/backup-recovery/backups">Cloud SQL Backups Overview Architecture</a></li><li><a href="https://cloud.google.com/sdk/gcloud/reference/sql/backups/delete">Documentation: gcloud sql backups delete</a></li><li><a href="https://cloud.google.com/sdk/gcloud/reference/sql/backups/list">Documentation: gcloud sql backups list</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3a357a2eac8d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PSQL On-prem to GCP Migration]]></title>
            <link>https://medium.com/@adarshpandey022/psql-on-prem-to-gcp-migration-d3f42c29e136?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/d3f42c29e136</guid>
            <category><![CDATA[database-migration]]></category>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[psql]]></category>
            <category><![CDATA[cloud]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Mon, 09 Sep 2024 20:06:47 GMT</pubDate>
            <atom:updated>2024-09-09T20:06:47.245Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GmC2oE4jKJWJ4hb-" /></figure><p>As businesses scale, cloud migration becomes a vital step in modernizing their infrastructure. Migrating databases like PostgreSQL from on-premises to Google Cloud Platform (GCP) offers benefits like scalability, security, and managed services. In this article, we’ll explore how to migrate your PostgreSQL database from an on-prem setup to GCP, using Google Cloud SQL and Google’s Database Migration Service (DMS).</p><h3>Why Migrate PostgreSQL to GCP?</h3><p>Google Cloud offers a fully managed PostgreSQL solution called <strong>Cloud SQL</strong>, which simplifies database management, supports automated backups, and ensures high availability. The migration process is streamlined using <strong>Google’s Database Migration Service (DMS)</strong>, which offers continuous replication with minimal downtime.</p><h3>Key Features of GCP for PostgreSQL Migration</h3><ul><li><strong>Cloud SQL for PostgreSQL</strong>: Fully managed, scalable PostgreSQL with automated backups, high availability, and built-in security features.</li><li><strong>Google DMS</strong>: Simplifies migrations with minimal downtime by supporting PostgreSQL, MySQL, and SQL Server.</li><li><strong>Security</strong>: Data is encrypted during transit and at rest, with options for SSL/TLS and VPN tunnels for additional security.</li></ul><h3>Security</h3><h4>Data Encryption:</h4><ul><li>Data is protected during migration. Database Migration Service supports multiple secure, private connectivity methods to protect your data in transit.</li><li>Use SSL/TLS to secure data in transit between the on-premises database and the GCP environment.</li><li>This ensures all data transmitted over the internet during the migration process is encrypted.</li><li>Once migrated, all data is encrypted by default, and Google Cloud databases provide multiple layers of security to meet even the most stringent requirements.</li></ul><h4>VPN Configuration:</h4><ul><li>Configure a VPN tunnel between on-premises infrastructure and GCP to establish a secure and private connection over the public internet.</li><li>Use Google Cloud VPN, supporting both site-to-site IPsec VPN connections and Cloud Interconnect for higher bandwidth and reliability.</li><li>Ensure the VPN configuration adheres to best practices for encryption algorithms and key management.</li></ul><h4>Access Controls:</h4><ul><li>Implement stringent access controls to limit who can initiate and manage the database migration process.</li><li>Use Identity and Access Management (IAM) roles and permissions to ensure only authorized personnel have the necessary access.</li><li>Employ multi-factor authentication (MFA) for an added layer of security.</li></ul><h4>Network Security:</h4><ul><li>Utilize firewall rules and security policies to restrict inbound and outbound traffic to necessary ports and IP addresses involved in the migration.</li><li>Use Virtual Private Cloud (VPC) firewall rules on GCP to control traffic flow and implement network segmentation.</li></ul><h4>Policy and Performance Considerations:</h4><ul><li>Check with the security administrator whether company policy forbids data transfers over the public internet.</li><li>Large-scale data transfers might negatively impact the performance of the production network.</li></ul><h3>Types of migration</h3><h4>Continuous migration</h4><p>Continuous migration involves a continuous flow of changes from a source to a destination following an initial full dump and load. Once the destination is ready, a promote operation is performed to make it the primary database.</p><p><strong>Process:</strong></p><ol><li>Take an initial snapshot of the source database (brief lockout).</li><li>Load the snapshot into the destination.</li><li>Recreate constraints (primary keys, foreign keys, indexes) on the destination.</li><li>Process ongoing changes (CDC) from source to destination.</li><li>When ready, stop writes to the source and promote the destination to the primary database.</li></ol><p><strong>Pros:</strong></p><ul><li><strong>Minimal Downtime:</strong> The source can continue to accept writes during most of the migration process, reducing overall downtime.</li><li><strong>Real-time Data Sync:</strong> Ongoing changes are continuously captured and applied to the destination, ensuring up-to-date data.</li><li><strong>Gradual Transition:</strong> Allows for a more seamless switch over to the new database with less impact on applications.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Complex Setup:</strong> Requires more configuration and monitoring to ensure continuous data capture and replication.</li><li><strong>Replication Delay:</strong> There might be a lag between the source and destination, leading to potential data consistency issues during the final promotion.</li><li><strong>Resource Intensive:</strong> Continuous replication can consume more resources, affecting performance.</li></ul><h4>One-time migration</h4><p>One-time migration is a single point-in-time snapshot of the database taken from the source and applied to the destination. The destination becomes the primary database once the load is completed.</p><p><strong>Process:</strong></p><ol><li>Stop writes to the source database.</li><li>Take a dump of the source database.</li><li>Load the dump into the destination.</li><li>Once the load is complete, automatically promote the destination to the primary database.</li></ol><p><strong>Pros:</strong></p><ul><li><strong>Simpler Process:</strong> Easier to set up and manage compared to continuous migration.</li><li><strong>No Replication Lag:</strong> Ensures consistency since the migration is done in one go without ongoing changes.</li><li><strong>Less Resource Intensive:</strong> Does not require continuous replication, reducing resource usage.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Higher Downtime:</strong> Requires stopping writes to the source database, leading to potential downtime for dependent applications.</li><li><strong>Data Freshness:</strong> Data is only as fresh as the last snapshot, so any changes after the dump won’t be captured until the next snapshot.</li><li><strong>Risk of Data Loss:</strong> If there are any issues during the migration, it could result in data loss or corruption without the ability to continuously sync.</li></ul><h3>Use Cases</h3><h4>Continuous Migration:</h4><ul><li>Ideal for mission-critical applications where downtime must be minimized.</li><li>Suitable for large databases where a gradual and controlled transition is necessary.</li><li>Useful when the source database must remain operational for writes during most of the migration process.</li></ul><h4>One-Time Migration:</h4><ul><li>Suitable for smaller databases or less critical applications where downtime is acceptable.</li><li>Ideal when a simple and quick migration process is preferred.</li><li>Appropriate when the source database can be easily stopped for the duration of the migration.</li></ul><h3>Migration Flow</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sT34bMKYR9Bp-sqU" /></figure><h4>1. Preparation and Prerequisites</h4><p>Before initiating the migration, ensure the following prerequisites are met:</p><ul><li>Install necessary extensions such as pglogical on your source PostgreSQL database to facilitate continuous replication.</li><li>Set up a secure connection between your on-prem environment and GCP using <strong>Google Cloud VPN</strong>.</li><li><a href="https://cloud.google.com/network-connectivity/docs/vpn/how-to/creating-ha-vpn">Learn more about VPN setup on GCP</a></li><li>Evaluate your on-premises environment to ensure it meets compatibility requirements for Cloud SQL.</li></ul><h4>2. Select the Appropriate Migration Type</h4><p>There are two common types of migration strategies for PostgreSQL databases on GCP:</p><p><strong>Continuous Migration</strong>: This involves continuous replication between your on-prem database and Cloud SQL.</p><ul><li><strong>Pros</strong>: Minimal downtime and real-time data sync.</li><li><strong>Cons</strong>: More complex to configure and resource-intensive.</li></ul><p><strong>One-Time Migration</strong>: A single snapshot of your database is migrated to GCP in one go.</p><ul><li><strong>Pros</strong>: Simpler and less resource-intensive.</li><li><strong>Cons</strong>: Requires stopping database writes during migration, leading to higher downtime.</li></ul><h4>3. Configuring Connectivity</h4><p>Ensure secure, encrypted connectivity between your on-prem database and GCP. Configure:</p><ul><li><strong>VPN</strong>: Set up a VPN tunnel to securely connect your on-prem environment to GCP.</li><li><strong>VPC Peering</strong>: Set up <strong>VPC peering</strong> for network connectivity between your on-prem and GCP environments.</li><li><a href="https://cloud.google.com/database-migration/docs/postgres/configure-connectivity-vpc-peering">VPC Peering setup guide</a></li></ul><h4>4. Create Connection Profiles</h4><p>Using Google Cloud Database Migration Service (DMS), create connection profiles for both the source (on-prem) and destination (Cloud SQL).</p><ul><li>Define the source as your on-prem PostgreSQL.</li><li>Define the destination as <strong>Cloud SQL for PostgreSQL</strong>.</li><li>Test the connectivity to ensure everything is properly configured.</li></ul><h4>5. Initiate the Migration Job</h4><p>Once the profiles are created, initiate the migration job:</p><ul><li>Choose the <strong>connectivity method</strong> (VPN or VPC Peering).</li><li>Configure and select the replication type (continuous or one-time).</li><li>Test the migration job before full execution to ensure that configurations are correct.</li><li><a href="https://cloud.google.com/database-migration/docs/postgres/create-migration-job">More on configuring migration jobs</a></li></ul><h4>6. Monitor the Migration Process</h4><p>Google’s DMS offers robust monitoring tools that provide real-time updates on your migration’s progress. Monitor the ongoing migration for potential issues like network latency, resource constraints, or replication lag.</p><ul><li>Use tools to monitor row counts and data consistency.</li><li>Set up <strong>cascading read replicas</strong> for testing, allowing you to validate the migration without affecting production systems.</li><li><a href="https://cloud.google.com/database-migration/docs/postgres/review-migration-job">Monitor your migration</a></li></ul><h4>7. Promote the Replica to Primary</h4><p>Once the migration is complete, promote the GCP Cloud SQL instance to your primary database. Ensure that you stop all writes to the source database before performing this step.</p><ul><li><a href="https://cloud.google.com/database-migration/docs/postgres/promote-migration">Promote the replica</a></li></ul><h3>Cascading read replicas for a Cloud SQL</h3><p>Database Migration Service lets you migrate data to a Cloud SQL destination instance, and then set up cascading read replicas for that instance. Cascading read replicas let you create a read replica under a Cloud SQL read replica in the same or different region before promoting your instance to primary.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4Q851U0U8QsqotoO" /></figure><h3>Data Validation</h3><p>After migration, it’s crucial to validate that the data in the Cloud SQL instance matches your on-prem database. This involves:</p><ul><li><strong>Row Counts Comparison</strong>: Ensure that the number of rows matches between the source and the destination.</li><li><strong>Checksum Verification</strong>: Generate checksums on both the source and target to verify data integrity.</li><li><a href="https://cloud.google.com/storage-transfer/docs/data-integrity">Data validation techniques</a></li></ul><p>Storage Transfer Service uses metadata available from the source storage system, such as checksums and file sizes, to ensure that data written to Cloud Storage is the same data read from the source.</p><p>If the checksum metadata on the source storage system indicates that the data Storage Transfer Service received doesn’t match the source data, the Storage Transfer Service records a failure for the transfer operation.</p><h3>Schema and Data Integrity Testing</h3><p>Run functional tests to verify that all relationships and constraints within the application are intact post-migration. This can be done by:</p><h4>Row Counts Comparison</h4><p>Ensure that the number of rows in each table matches between the source and destination databases. Execute the following query for each table:</p><pre>SELECT COUNT(*) FROM &lt;table_name&gt;;</pre><h4>Checksum Verification</h4><p>This verifies that the data content is identical between the source and destination databases. Generate checksums for each table. This can be done using functions like pg_checksums or custom scripts:</p><pre>SELECT md5(string_agg(t::text, &#39;&#39;)) FROM (SELECT * FROM &lt;table_name&gt; ORDER BY &lt;primary_key&gt;) t;</pre><h4>Data Sampling and Comparison</h4><p>Ensure that sampled data points are identical in both databases. Randomly select a sample of rows from each table:</p><pre>SELECT * FROM &lt;table_name&gt; ORDER BY RANDOM() LIMIT &lt;sample_size&gt;;</pre><h3>What Isn’t Migrated by Google DMS</h3><p>Google’s DMS supports a wide variety of data migrations, but there are several key elements that are not migrated automatically. Understanding these exclusions can help you prepare the necessary manual steps to ensure a smooth transition:</p><ol><li><strong>Large Objects (LOBs):</strong> PostgreSQL’s logical decoding does not support replicating large objects. Rows referencing large objects are replicated, but the large object itself is not, meaning attempts to access them on the destination will fail.</li><li><strong>Tables without Primary Keys:</strong> For tables that lack primary keys, Google DMS can only replicate the initial snapshot and INSERT operations. Any UPDATE or DELETE statements must be manually migrated.</li><li><strong>Materialized Views:</strong> Only the schema of materialized views is migrated. The data within these views is not copied over. To populate them after migration, you must manually execute a REFRESH MATERIALIZED VIEW command.</li><li><strong>SEQUENCE States:</strong> The SEQUENCE states, such as last_value, may differ between the source and destination after migration. This difference must be addressed post-migration to maintain continuity in the sequence generation.</li><li><strong>Custom Tablespaces:</strong> Customized tablespaces are not migrated. All data is moved to the default pg_default tablespace in Cloud SQL.</li><li><strong>User Accounts:</strong> DMS does not migrate user accounts. To add users to a Cloud SQL instance, this must be done manually through the Google Cloud console or a PostgreSQL client.</li></ol><h3>Known Limitations of Google DMS</h3><p>Google DMS, while powerful, has certain limitations that affect the migration process:</p><ol><li><strong>DDL Replication:</strong> Data Definition Language (DDL) changes, such as table structure modifications, are not replicated by default. To propagate DDL changes, users need to utilize the pglogical.replicate_ddl_command function. DDL changes must be manually synchronized between the source and destination databases.</li><li><strong>Unlogged and Temporary Tables:</strong> Neither unlogged nor temporary tables are supported for replication in Google DMS.</li><li><strong>Encryption Issues:</strong> If source databases are encrypted with customer-managed keys that DMS cannot access, the migration process will fail. However, if the data is encrypted using the pgcrypto extension, it can be migrated successfully.</li><li><strong>Writable Destination:</strong> The destination database remains writable during migration, allowing for DDL changes. However, altering database configurations or table structures during this phase can disrupt the migration process or compromise data integrity.</li><li><strong>Materialized Views:</strong> Materialized views require manual refreshing after migration. This extra step is often necessary to ensure the migrated database is fully functional.</li></ol><h3>Common Causes of Data Migration Issues</h3><p>Even with a well-structured migration plan, certain issues may arise due to various environmental or technical factors. Being aware of these common causes of migration problems can help you mitigate risks and ensure a successful migration:</p><ol><li><strong>Network or Connectivity Problems:</strong> Network instability or insufficient bandwidth can slow data transfer or cause connectivity failures between on-premises systems and Google Cloud. This is especially critical for continuous migrations where real-time synchronization is essential.</li><li><strong>Data Format or Encoding Errors:</strong> Incompatible data formats or incorrect character encoding between the source and destination databases can lead to migration failures or corrupted data. Ensure that both environments are using compatible formats before starting the migration.</li><li><strong>Resource Limitations:</strong> Insufficient disk space, CPU, or memory on either the source or destination systems can result in slow migrations or failed processes. Planning for resource allocation is especially important for large databases that demand significant bandwidth and compute power.</li><li><strong>Permissions and Access Control Issues:</strong> Misconfigured service accounts or IAM roles can prevent DMS from accessing source or target databases. It’s crucial to ensure that the correct permissions are granted to the accounts managing the migration.</li></ol><h3>Conclusion</h3><p>Migrating databases from on-premises infrastructure to Google Cloud Platform (GCP) using Google Database Migration Service (DMS) offers organizations a robust and secure solution to modernize their database environments. The process simplifies the transfer of various database workloads, such as MySQL, PostgreSQL, and Oracle, to GCP services like Cloud SQL and AlloyDB. Continuous data replication and minimal downtime during the migration ensure smooth operations for mission-critical applications.</p><p>Security is paramount, with GCP providing end-to-end encryption for data in transit and at rest, while VPN and firewall configurations further safeguard the migration process. Access control measures, including IAM roles and multi-factor authentication (MFA), help secure the entire migration pipeline.</p><p>Two migration methods — continuous and one-time — offer flexibility based on the size and criticality of the databases. While continuous migration minimizes downtime and ensures real-time synchronization, it can be resource-intensive and complex to manage. In contrast, one-time migration is simpler and more suitable for less critical applications but involves longer downtime.</p><p>In addition to the technical execution, organizations must carefully consider policy and performance implications, such as security restrictions on data transfers and the potential impact of large-scale data movements on network performance. By adhering to GCP’s best practices for network security, data validation, and application-level testing, organizations can ensure a seamless and secure migration with minimized risks.</p><h3>Reference Links</h3><ul><li><a href="https://cloud.google.com/network-connectivity/docs/vpn/how-to/creating-ha-vpn">Creating HA VPN</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/configure-connectivity-vpc-peering">Configure Connectivity — VPC Peering</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/configure-source-database#pglogical">Configure Source Database</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/create-source-connection-profile">Create Source Connection Profile</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/create-migration-job">Create Migration Job</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/review-migration-job">Review Migration Job</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/set-up-cascading-replica">Set up Cascading Replica</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/promote-migration">Promote Migration</a></li><li><a href="https://cloud.google.com/storage-transfer/docs/data-integrity">Data Integrity</a></li><li><a href="https://cloud.google.com/database-migration/docs/postgres/known-limitations">Known Limitations of Database Migration Service</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d3f42c29e136" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Create a Custom GCP Service Account Key with an Expiry Date]]></title>
            <link>https://medium.com/@adarshpandey022/create-a-service-account-key-with-a-custom-expiry-using-openssh-7b229ed5c94d?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/7b229ed5c94d</guid>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[service-account-key]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Wed, 30 Nov 2022 14:50:28 GMT</pubDate>
            <atom:updated>2026-04-25T11:15:11.402Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*reWeiCYxwn26NzCj" /></figure><h3>Create a Custom GCP Service Account Key with an Expiry Date</h3><h3>Introduction</h3><p>Managing service account (SA) keys effectively is a critical foundational step for maintaining rigorous security perimeters within Google Cloud Platform (GCP). Unlike user identities, service accounts are non-human entities meant for programmatic access. When you download a JSON key for a service account, you are inherently taking a massive security risk: that static key never expires by default unless manually deleted.</p><p>One extremely effective way to immediately mature your cloud security posture is by deliberately generating custom keys with hardcoded, predefined expiration dates. This straightforward cryptographic practice drastically reduces the likelihood of stale, forgotten credentials being systematically leaked and misused by bad actors in the wild.</p><h3>The Challenge: The Threat of Stale Credentials</h3><p>GCP Console allows you to easily click “Create New Key,” delivering a JSON file valid indefinitely. Over months, engineers download these keys to test local scripts, configure third-party CI/CD tools, or share them via insecure channels. When an employee leaves or a project concludes, these orphaned keys remain active, essentially serving as immortal backdoor passes into your cloud environment.</p><p>Common Pitfall: Hardcoding indefinite service account keys into application source code or Docker containers. If the source repository is compromised, the attacker instantly gains untethered access to your GCP infrastructure.</p><p>[Insert Image: Threat modeling diagram showing how a leaked JSON key from a developer’s laptop can be used to exfiltrate data from a GCP project.]</p><h3>The Solution/Process: Automated Custom Key Expiry</h3><p>In this technical guide, we’ll walk through precisely how to create a custom GCP service account key with an embedded expiration date using a remarkably simple and elegant Bash script. This automated process involves cleanly generating a local RSA key pair utilizing OpenSSL and securely configuring the service account key via the GCP API for safe, time-limited use.</p><h3>Prerequisites</h3><p>Before executing the script, rigorously ensure the following dependencies are met:</p><ul><li>You have an authenticated version of the Google Cloud SDK (gcloud) configured locally.</li><li>You possess elevated IAM permissions (roles/iam.serviceAccountKeyAdmin) forcing key uploads for the target SA.</li><li>The `openssl` and `jq` command-line utilities are installed.</li></ul><h3>Script Breakdown</h3><h4>1. Generate RSA Key Pair</h4><p>Using the battle-tested openssl utility, the script dynamically generates a fresh RSA key pair locally. The critical -days flag mathematically defines the certificate&#39;s rigid expiration period (e.g., 90 days).</p><pre>openssl req -x509 -nodes -newkey rsa:2048 -days &quot;90&quot; \<br>  -keyout ./private_key.pem \<br>  -out ./public_key.pem \<br>  -subj &quot;/CN=unused&quot;</pre><h4>2. Upload the Public Key to the Service Account</h4><p>The safe public key is transmitted and uploaded via the API to the target service account utilizing the gcloud iam service-accounts keys upload command. GCP accepts the public key and trusts the expiration date embedded within the certificate.</p><pre>OUTPUT=$(gcloud iam service-accounts keys upload ./public_key.pem \<br>  --iam-account=&quot;${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com&quot; \<br>  --project=${PROJECT_ID} 2&gt;&amp;1)</pre><p>Pro-Tip: Always delete the raw private_key.pem file from your local disk space immediately after formulating the final JSON structure.</p><h4>3. Formulate the JSON Key File</h4><p>The final, usable credential payload is safely constructed and saved in the standard Google JSON format utilizing jq. The sensitive private key and metadata are securely templated.</p><pre>jq -n \<br>  --arg PRIVATE_KEY &quot;$(cat ./private_key.pem)&quot; \<br>  --arg PROJECT_ID &quot;$PROJECT_ID&quot; \<br>  --arg CLIENT_EMAIL &quot;${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com&quot; \<br>  --arg UNIQUE_ID &quot;$UNIQUE_ID&quot; \<br>  --arg KEY_ID &quot;$KEY_ID&quot; \<br>  &#39;{<br>    &quot;type&quot;: &quot;service_account&quot;,<br>    &quot;project_id&quot;: $PROJECT_ID,<br>    &quot;private_key_id&quot;: $KEY_ID,<br>    &quot;private_key&quot;: $PRIVATE_KEY,<br>    &quot;client_email&quot;: $CLIENT_EMAIL,<br>    &quot;client_id&quot;: $UNIQUE_ID,<br>    &quot;auth_uri&quot;: &quot;https://accounts.google.com/o/oauth2/auth&quot;,<br>    &quot;token_uri&quot;: &quot;https://oauth2.googleapis.com/token&quot;,<br>    &quot;auth_provider_x509_cert_url&quot;: &quot;https://www.googleapis.com/oauth2/v1/certs&quot;,<br>    &quot;client_x509_cert_url&quot;: &quot;https://www.googleapis.com/robot/v1/metadata/x509/\($CLIENT_EMAIL)&quot;,<br>    &quot;universe_domain&quot;: &quot;googleapis.com&quot;<br>  }&#39; &gt; private-key.json</pre><p>[Insert Image: Diagram illustrating the flow: OpenSSL generating the keypair `-&gt;` gcloud uploading the public key `-&gt;` jq assembling the final private JSON key combining GCP metadata.]</p><h3>Key Takeaways</h3><ul><li>Standard JSON service account keys downloaded from the GCP Console never expire, presenting a massive security vulnerability.</li><li>Forcing keys to expire natively via OpenSSL ensures compromised credentials are automatically rendered useless after a short set period.</li><li>Automating key rotation via scripts perfectly aligns with strict organizational InfoSec policies and compliance frameworks (like SOC2).</li></ul><h3>Conclusion</h3><p>By fully automating the reliable creation of service account keys and structurally embedding expiration dates via x509 certificates, infrastructure teams can decisively close one of the most common cloud security gaps. This agile scripting approach ensures that leaked or stale credentials literally cannot linger indefinitely. You can trivially parameterize this script to plug straight into your bespoke CI/CD pipelines to automatically bootstrap time-limited developer environments safely.</p><h3>Further Reading</h3><ul><li><a href="https://cloud.google.com/iam/docs/creating-managing-service-account-keys">GCP Official Docs: Creating and managing service account keys</a></li><li><a href="https://cloud.google.com/iam/docs/best-practices-for-managing-service-account-keys">GCP Official Docs: Best practices for managing service account keys</a></li><li><a href="https://www.openssl.org/docs/man3.0/man1/openssl-req.html">OpenSSL Open Source Reference: req</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7b229ed5c94d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cloud SQL scheduler using Cloud Scheduler HTTP URL method (GCP)]]></title>
            <link>https://medium.com/@adarshpandey022/cloud-sql-scheduler-using-cloud-scheduler-http-url-method-gcp-c80d02b9e25?source=rss-d38721a4bc98------2</link>
            <guid isPermaLink="false">https://medium.com/p/c80d02b9e25</guid>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[gcp-cost-management]]></category>
            <category><![CDATA[google-cloud-sql]]></category>
            <dc:creator><![CDATA[Adarsh Pandey]]></dc:creator>
            <pubDate>Wed, 30 Nov 2022 11:37:22 GMT</pubDate>
            <atom:updated>2023-09-23T10:47:33.517Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/878/1*9TXuHGS4xLxBJUpYD9Qh3g.png" /></figure><p>In the world of cloud development, cost optimization is key. If you’re using a Cloud SQL instance as a development server, you most likely don’t need it running 24/7. In fact, keeping it active around the clock can significantly inflate your cloud costs. But fear not, there’s a smart solution!</p><p>In this blog post, we’ll show you how to effectively reduce your Cloud SQL expenses by scheduling your development server to start up every morning when your workday begins and automatically stop every evening when you’ve completed your development tasks.</p><h3>Why Schedule Your Cloud SQL Instance?</h3><h4>1. Cost Savings</h4><p>Running your Cloud SQL instance continuously can quickly add up in terms of operational expenses. By scheduling its activity to align with your work hours, you can enjoy substantial cost savings without compromising on availability.</p><h4>2. Resource Efficiency</h4><p>Scheduling your instance ensures that cloud resources are allocated only when needed. This promotes efficient utilization of your cloud infrastructure, leaving no room for unnecessary idle time.</p><h4>3. Eco-Friendly Computing</h4><p>Reducing your server’s runtime not only benefits your wallet but also the environment. By scheduling start and stop times, you contribute to a greener, more sustainable cloud ecosystem.</p><h3>How to Set Up Scheduled Start and Stop</h3><p>In this blog post, we’ll walk you through the process of configuring your Cloud SQL instance to automatically start and stop on your business days using Google Cloud Scheduler. We’ll provide step-by-step instructions and best practices to ensure a seamless setup.</p><h3>Before You Begin</h3><p>Before diving into scheduling your Cloud SQL instance, there are a few important prerequisites to keep in mind:</p><p><strong>Billing Enabled:</strong> Ensure that billing is enabled for your Cloud project. This is crucial for all cloud services, including Cloud SQL, to function properly.</p><p><strong>Enable Cloud SQL Administration API:</strong> If you haven’t already done so, enable the Cloud SQL Administration API. You can do this by navigating to [<a href="https://console.developers.google.com/apis/api/sqladmin](https://console.developers.google.com/apis/api/sqladmin)">https://console.developers.google.com/apis/api/sqladmin](https://console.developers.google.com/apis/api/sqladmin)</a> and making sure it’s activated for your project.</p><p><strong>Check Quota:</strong> It’s essential to check the quota for your project to ensure that you have sufficient resources available for your Cloud SQL instance. Running into quota limitations can disrupt your scheduling plans.</p><p><strong>Activation Policy: </strong>When starting, stopping, or restarting a Cloud SQL instance, you’ll need to set an activation policy. This policy determines whether the instance is activated to accept connection requests.</p><p>- For MySQL instances, it’s generally advisable to set the activation policy to ALWAYS if you want the instance to accept connection requests when active.<br> <br> — If you’re not actively using your instance, you can set its activation policy to NEVER to avoid incurring instance charges during idle periods. Please note that NEVER is not supported for read replica instances.</p><p>With these prerequisites in place, you’ll be well-prepared to efficiently schedule the start and stop times for your Cloud SQL instance, optimizing both cost and resource utilization.</p><h3>Creating a Cloud Scheduler Job</h3><p>To set up a Cloud Scheduler job for your Cloud SQL instance, follow these steps:</p><p>1. In the Google Cloud console, navigate to the Cloud Scheduler.</p><p>2. Click on “CREATE JOB.”</p><p>3. Provide a unique Job name for your scheduler. This name must be distinct from other jobs in the same region.</p><p>4. Select your preferred Region.</p><p>5. Optionally, you can include a short description of this Cloud Scheduler job.</p><p>6. Specify the frequency at which you want to schedule this job. Schedules are defined using the Unix-cron format.</p><p>7. Select your Time Zone.</p><p>8. Click “CONTINUE.”</p><p>9. Set the target type as “HTTP.”</p><p>10. In the URI section, paste the following URL, replacing `$PROJECT-NAME` and `$SQL-INSTANCE-NAME` with your respective GCP Project ID and Cloud SQL instance name:</p><pre> https://www.googleapis.com/sql/v1beta4/projects/$PROJECT-NAME/instances/$SQL-INSTANCE-NAME</pre><p>11. Choose the HTTP method as “PATCH.”</p><p>12. Add two HTTP Headers as specified below:</p><ul><li>Header 1:</li></ul><pre>Name: Content-Type<br>Value: application/octet-stream</pre><ul><li>Header 2:</li></ul><pre>Name: User-Agent<br>Value: Google-Cloud-Scheduler</pre><p>13. In the Body section, if you want to **Start** the SQL instance, provide the following payload:</p><pre>{<br> &quot;settings&quot;: {<br> &quot;activationPolicy&quot;: &quot;ALWAYS&quot;<br> }<br> }</pre><p>14. In the Body section, if you want to **Stop** the SQL instance, provide the following payload:</p><pre>{<br> &quot;settings&quot;: {<br> &quot;activationPolicy&quot;: &quot;NEVER&quot;<br> }<br> }</pre><p>15. Under the Auth Header, select “Add OAuth token.”</p><p>16. Choose a service account that has the necessary permissions to start/stop Cloud SQL instances.</p><p>17. In the scope section, mention one of the following URLs based on your requirements:</p><pre>https://www.googleapis.com/auth/cloud-platform<br>https://www.googleapis.com/auth/sqlservice.admin</pre><p>With these configurations, your Cloud Scheduler job is ready to efficiently manage the start and stop actions of your Cloud SQL instance according to your defined schedule. This automation will help you optimize costs and resource utilization effortlessly.</p><h3>Reference Material</h3><p>For further guidance and reference on scheduling Cloud SQL instances, here are some useful resources:</p><p><strong>How to start an instance, stop an instance, and restart an instance that is running:</strong><br>This official Google Cloud documentation provides step-by-step instructions on starting, stopping, and restarting a running Cloud SQL instance.</p><p><a href="https://cloud.google.com/sql/docs/mysql/start-stop-restart-instance#rest-v1_1">Read more</a></p><p><strong>To see how the underlying REST API request is constructed for this task:</strong><br> If you’re interested in the technical details and underlying REST API requests used for starting and stopping Cloud SQL instances, this documentation offers insights.</p><p><a href="https://cloud.google.com/sql/docs/mysql/admin-api/rest/v1beta4/instances/patch">Read more</a></p><p><strong>Cloud SQL instance to start and stop each workday using Cloud Functions, Cloud Pub/Sub, and Cloud Scheduler:</strong><br>Explore this comprehensive guide to setting up automated start and stop schedules for your Cloud SQL instances using a combination of Cloud Functions, Cloud Pub/Sub, and Cloud Scheduler. This blog post provides a hands-on example and additional insights into cost optimization.</p><p><a href="https://cloud.google.com/blog/topics/developers-practitioners/lower-development-costs-schedule-cloud-sql-instances-start-and-stop">Read more</a></p><p>These resources will complement your understanding of scheduling Cloud SQL instances and help you implement efficient cost-saving practices in your Google Cloud environment.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c80d02b9e25" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>