<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jonathan ES Lin</title>
    <description>The latest articles on Forem by Jonathan ES Lin (@ernsheong).</description>
    <link>https://forem.com/ernsheong</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F102857%2F81dd2910-af7b-4f60-bb8a-3ec8632b0f0a.jpeg</url>
      <title>Forem: Jonathan ES Lin</title>
      <link>https://forem.com/ernsheong</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ernsheong"/>
    <language>en</language>
    <item>
      <title>Managing background jobs with Cloud Tasks</title>
      <dc:creator>Jonathan ES Lin</dc:creator>
      <pubDate>Tue, 23 Jun 2020 08:10:00 +0000</pubDate>
      <link>https://forem.com/ernsheong/managing-background-jobs-with-cloud-tasks-2a2e</link>
      <guid>https://forem.com/ernsheong/managing-background-jobs-with-cloud-tasks-2a2e</guid>
      <description>&lt;p&gt;This post was originally posted on &lt;a href="https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/"&gt;JonCloudGeek&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Overview&lt;/li&gt;
&lt;li&gt;Relationship with App Engine&lt;/li&gt;
&lt;li&gt;Targets&lt;/li&gt;
&lt;li&gt;Create a queue&lt;/li&gt;
&lt;li&gt;Configuring a queue&lt;/li&gt;
&lt;li&gt;Rate-limit parameters&lt;/li&gt;
&lt;li&gt;Retry parameters&lt;/li&gt;
&lt;li&gt;Scheduling a task&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Cloud Tasks vs Cloud Pub/Sub&lt;/li&gt;
&lt;li&gt;Cloud Tasks vs Cloud Scheduler&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZZek_KoP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/meta.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZZek_KoP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/meta.jpg" alt="A queue" title="A queue."&gt;&lt;/a&gt;A queue.&lt;/p&gt;

&lt;p&gt;In this blog post, I will give an overview of &lt;a href="https://cloud.google.com/tasks"&gt;Cloud Tasks&lt;/a&gt; with the aim of enabling you to start using it in your own applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cloud.google.com/tasks"&gt;Cloud Tasks&lt;/a&gt; is a fully managed service that allows you to &lt;strong&gt;execute&lt;/strong&gt;, &lt;strong&gt;dispatch&lt;/strong&gt;, and &lt;strong&gt;deliver&lt;/strong&gt; a large number of distributed tasks. Use Cloud Tasks to perform work asynchronously outside of a user or service-to-service request cycle.&lt;/p&gt;

&lt;p&gt;Well, that's a paraphrase of the &lt;a href="https://cloud.google.com/tasks/docs"&gt;documentation intro&lt;/a&gt;. What exactly is Cloud Tasks? In a nutshell, &lt;strong&gt;Cloud Tasks helps you manage queues of tasks&lt;/strong&gt; that are performed outside a request cycle (in the background).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lizpr3aJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/cloud-tasks-logo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lizpr3aJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/cloud-tasks-logo.png" alt="Cloud Tasks" title="Cloud Tasks"&gt;&lt;/a&gt;Cloud Tasks&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;task&lt;/strong&gt; is the &lt;strong&gt;encapsulation of information representing an independent piece of work&lt;/strong&gt; that triggers a request to a &lt;strong&gt;handler&lt;/strong&gt; to complete the task (handler is the code that runs on a certain endpoint &lt;strong&gt;target&lt;/strong&gt;). The task remains in the &lt;strong&gt;queue&lt;/strong&gt; which persists the task until the triggered handler completes with a successful status code. If the handler suffers from a failure or an error, the queue will retry the task again later (with backoff). It will also rate-limit the number of concurrent tasks that is simultaneously executed, hence saving your worker endpoint from certain "drowning" otherwise.&lt;/p&gt;

&lt;p&gt;As a simple example, sending an email based on a user action should ideally be done asynchronously as a task, allowing you to return from the request more quickly, and ensuring that the email is actually sent in the event of a failure in the sender gateway.&lt;/p&gt;

&lt;p&gt;You will first create and configure the queue, which is then managed by Cloud Tasks. Complexities associated with task management such as latency, server crashes, resource consumption limitations, and retry management is handled by Cloud Tasks.&lt;/p&gt;

&lt;p&gt;Each task is made up of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A unique name&lt;/strong&gt; (generated for you by client SDKs, usually)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration information&lt;/strong&gt; (e.g. url, timeout, HTTP method)&lt;/li&gt;
&lt;li&gt;(optional) &lt;strong&gt;Payload&lt;/strong&gt; of data necessary to process the request. The payload is send in the request body, thus handlers that process tasks with payloads must use POST or PUT as the HTTML method.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Relationship with App Engine
&lt;/h2&gt;

&lt;p&gt;Historically, Cloud Tasks had its origins in App Engine. Indeed, if you use the first generation App Engine standard environment, you should use Cloud Tasks via the App Engine Task Queue API (if you are new to App Engine standard you should use the second generation instead). All other users (second generation App Engine standard, App Engine flex, Compute Engine, Cloud Run, etc.) should use the Cloud Tasks API, which we are interested in.&lt;/p&gt;

&lt;p&gt;At time of writing, Cloud Tasks requires you to have a project with App Engine configured. &lt;strong&gt;The App Engine app hosts the Cloud Task queues that are created&lt;/strong&gt; (note that this "App Engine app" is really internal Google infrastructure that is somewhat coupled with App Engine, but you can disable App Engine in your project). Particularly, the App Engine app is &lt;strong&gt;located in a specific region which serves the location of your queues in Cloud Tasks&lt;/strong&gt;. Hence, you should give some thought to where your App Engine app is going to be, because once it is set for your project you cannot change it without creating another project. This limitation kinda sucks because it would be nice to just be able to spin up queues wherever I like, like how I can spin up a function in Cloud Functions in any supported region.&lt;/p&gt;

&lt;p&gt;Note that, because of this, disabling App Engine in your project will cause Cloud Tasks to stop working, whether or not you use App Engine handlers or HTTP handlers (see next section).&lt;/p&gt;

&lt;h2&gt;
  
  
  Targets
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AOTVC96L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/target.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AOTVC96L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/target.png" alt="A target" title="A target."&gt;&lt;/a&gt;A target.&lt;/p&gt;

&lt;p&gt;The endpoints that process the tasks are called &lt;strong&gt;targets&lt;/strong&gt;, where the &lt;strong&gt;handlers&lt;/strong&gt; are defined. Cloud Tasks supports two types of targets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(Generic) &lt;strong&gt;HTTP targets&lt;/strong&gt; are hosted at any generic HTTP endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Engine targets&lt;/strong&gt; are hosted in a service on App Engine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both cases, all handlers must send a &lt;code&gt;2xx&lt;/code&gt; HTTP response code before a certain timeout. For HTTP targets, the deadline is 10 minutes by default (extendable to 30 minutes). For App Engine targets, the deadline depends on the &lt;a href="https://cloud.google.com/tasks/docs/creating-appengine-handlers#timeouts"&gt;scaling type of the service&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog post, I will solely focus on HTTP targets, as it is the more generic and likely use case for most users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a queue
&lt;/h2&gt;

&lt;p&gt;Create a Cloud Tasks queue via the Cloud SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud tasks queues create &lt;span class="o"&gt;[&lt;/span&gt;QUEUE_ID]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;describe&lt;/code&gt; to inspect your queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud tasks queues describe &lt;span class="o"&gt;[&lt;/span&gt;QUEUE_ID]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The output should be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;name: projects/[PROJECT_ID]/locations/[LOCATION_ID]/queues/[QUEUE_ID]
 rateLimits:
   maxBurstSize: 100
   maxConcurrentDispatches: 1000
   maxDispatchesPerSecond: 500.0
 retryConfig:
   maxAttempts: 100
   maxBackoff: 3600s
   maxDoublings: 16
   minBackoff: 0.100s
 state: RUNNING
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note the available configuration above which we will explore below: &lt;code&gt;maxBurstSize&lt;/code&gt;, &lt;code&gt;maxConcurrentDispatches&lt;/code&gt;, &lt;code&gt;maxDispatchedPerSecond&lt;/code&gt;, &lt;code&gt;maxAttempts&lt;/code&gt;, &lt;code&gt;maxBackoff&lt;/code&gt;, &lt;code&gt;maxDoublings&lt;/code&gt;, and &lt;code&gt;minBackoff&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring a queue
&lt;/h2&gt;

&lt;p&gt;There are three aspects to configuring your queues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt; allow you to define the maximum rate and maximum number of concurrent tasks that can be dispatched by a queue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry parameters&lt;/strong&gt; allow you to specify the maximum number of times to retry failed tasks, set a time limit for retry attempts, and control the interval between attempts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing&lt;/strong&gt; (App Engine targets only, not covered here)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rate-limit parameters
&lt;/h3&gt;

&lt;p&gt;Cloud Tasks uses the &lt;a href="https://en.wikipedia.org/wiki/Token_bucket"&gt;token bucket algorithm&lt;/a&gt; to enforce rate-limiting. In essence, we have a bucket that have a fixed capacity of tokens. A token represents a single unit added to the bucket at a fixed rate. Note that a token does &lt;em&gt;not&lt;/em&gt; represent a task, it is just a token.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A token is added to the bucket every 1/&lt;em&gt;r&lt;/em&gt; seconds, at rate &lt;em&gt;r&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The bucket can hold at the most &lt;em&gt;b&lt;/em&gt; tokens. If a token arrives when the bucket is full, it is discarded.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When a &lt;strong&gt;task&lt;/strong&gt; is scheduled, if there is at least 1 token in the bucket, a token is removed from the bucket, and the task is executed. If no tokens are available in the bucket, no tokens are removed from the bucket, and the task remains on the queue.&lt;/p&gt;

&lt;p&gt;If multiple tasks are generated within a short time, the tasks are dispatched concurrently subject to token availability, up to the value set in &lt;code&gt;maxConcurrentDispatches&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Therefore, we now have a better understanding of what we are configuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;maxDispatchesPerSecond&lt;/code&gt; is the rate at which &lt;em&gt;tokens&lt;/em&gt; are continuously added into the bucket. While related, is it &lt;em&gt;not&lt;/em&gt; the rate at which tasks are dispatched (they are equivalent only if there is a relatively steady flow of tasks, or if there is a backlog in the queue).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maxConcurrentDispatches&lt;/code&gt; is the maximum number of tasks in the queue that can run at once (concurrency).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maxBurstSize&lt;/code&gt; is the &lt;strong&gt;bucket size&lt;/strong&gt;. It is set automatically by Cloud Tasks API based on &lt;code&gt;maxDispatchesPerSecond&lt;/code&gt; (you cannot change it). Cloud Tasks will set this to a number that ensures an efficient rate for managing bursts. It is possible to change this number manually by using a &lt;code&gt;queue.yaml&lt;/code&gt;, but this is not generally recommended (see &lt;a href="https://cloud.google.com/tasks/docs/queue-yaml"&gt;Using Queue Management versus queue.yaml&lt;/a&gt; for more information).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;code&gt;update&lt;/code&gt; to configure the above via Cloud SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud tasks queues update &lt;span class="o"&gt;[&lt;/span&gt;QUEUE_ID] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-dispatches-per-second&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MAX_DISPATCHES_PER_SECOND] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-concurrent-dispatches&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MAX_CONCURRENT_DISPATCHES]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Retry parameters
&lt;/h3&gt;

&lt;p&gt;If a task fails (e.g. handler timeout, handler error), Cloud Tasks will retry the task with exponential backoff according to the parameters shown below.&lt;/p&gt;

&lt;p&gt;Unlike rate-limits, retry paramaters are more straightforward, so let's jump straight into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud tasks queues update &lt;span class="o"&gt;[&lt;/span&gt;QUEUE_ID] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-attempts&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MAX_ATTEMPTS] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--min-backoff&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MIN_BACKOFF] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-backoff&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MAX_BACKOFF] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-doublings&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MAX_DOUBLINGS] &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-retry-duration&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MAX_RETRY_DURATION]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MAX_ATTEMPTS&lt;/code&gt; is the maximum number of attempts for a task, including the first attempt. You can allow unlimited retries by setting this flag to &lt;code&gt;unlimited&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MIN_BACKOFF&lt;/code&gt; is the minimum amount of time to wait between retry attempts. The value must be a string that ends in "s", such as 5s.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MAX_BACKOFF&lt;/code&gt; is the maximum amount of time to wait between retry attempts. The value must be a string that ends in "s", such as 5s.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MAX_DOUBLINGS&lt;/code&gt; is the maximum number of times that the interval between failed task retries will be doubled before the increase becomes constant.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MAX_RETRY_DURATION&lt;/code&gt; is the maximum amount of time for retrying a failed task. The value must be a string that ends in "s", such as 5s.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scheduling a task
&lt;/h2&gt;

&lt;p&gt;You would usually create a task using one of the &lt;a href="https://cloud.google.com/apis/docs/cloud-client-libraries"&gt;Google Cloud Client Libraries&lt;/a&gt; from within your own server application.&lt;/p&gt;

&lt;p&gt;Below is a code sample for Node.js (see &lt;a href="https://cloud.google.com/tasks/docs/creating-http-target-tasks#node.js"&gt;Creating HTTP Target tasks&lt;/a&gt; for source and samples in other languages):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CloudTasksClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@google-cloud/tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Instantiates a client.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CloudTasksClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Construct the fully qualified queue name.&lt;/span&gt;
&lt;span class="c1"&gt;// TODO(developer): Uncomment these lines and replace with your values.&lt;/span&gt;
&lt;span class="c1"&gt;// const project = 'my-project-id';&lt;/span&gt;
&lt;span class="c1"&gt;// const queue = 'my-queue';&lt;/span&gt;
&lt;span class="c1"&gt;// const location = 'us-central1';&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queuePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;httpRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;httpMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/taskhandler&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Full URL path to task handler endpoint&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;httpRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inSeconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The time when the task is scheduled to be attempted.&lt;/span&gt;
  &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scheduleTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inSeconds&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Send create task request.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Interestingly, you can schedule a task in the future with &lt;code&gt;scheduleTime&lt;/code&gt;. Also, with &lt;code&gt;dispatchDeadline&lt;/code&gt; you can change the default timeout for the task handler. See the &lt;a href="https://googleapis.dev/nodejs/tasks/latest/google.cloud.tasks.v2.Task.html"&gt;documentation&lt;/a&gt; for more options.&lt;/p&gt;

&lt;p&gt;Once a task is created, attempts will be made to call the task handler at the given URL. There is nothing special about the task handler, but it will have to anticipate the format of the request (JSON or otherwise?) in the request body (if present). In other words, it is just like any HTTP handler in your API.&lt;/p&gt;

&lt;p&gt;The task &lt;strong&gt;name&lt;/strong&gt; is not given explicitly here, so the client library will generate one for us. I did not test this out, but I expect that if I generated the task name myself, subsequent task creations with the same name will be &lt;strong&gt;deduplicated&lt;/strong&gt;. This feature might be useful in your use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;The biggest security concern which I will address here is ensuring that no one else but Cloud Tasks is allowed to invoke the task handlers.&lt;/p&gt;

&lt;p&gt;In the case of &lt;strong&gt;App Engine targets&lt;/strong&gt;, this is easy. App Engine will set &lt;a href="https://cloud.google.com/tasks/docs/creating-appengine-handlers#reading_app_engine_task_request_headers"&gt;specific headers&lt;/a&gt; such as &lt;code&gt;X-AppEngine-TaskName&lt;/code&gt; and &lt;code&gt;X-AppEngine-QueueName&lt;/code&gt;, which are set internally and if an attacker tries to set it externally it will be removed by App Engine. If any of the headers are present in your task handler, you can trust that the request is a Cloud Tasks request.&lt;/p&gt;

&lt;p&gt;In the case of &lt;strong&gt;HTTP targets&lt;/strong&gt;, however, &lt;a href="https://cloud.google.com/tasks/docs/creating-http-target-tasks#handler"&gt;similar headers&lt;/a&gt; are also set by Cloud Tasks, but they are for information only and cannot be trusted as sources of identity. Instead, you need to &lt;a href="https://developers.google.com/identity/protocols/oauth2/openid-connect?#validatinganidtoken"&gt;validate an OIDC token&lt;/a&gt; provided by Cloud Tasks. This is out of the scope of this blog post for now; I may come back and update later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Tasks vs Cloud Pub/Sub
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zN1-qGSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/cloud-pubsub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zN1-qGSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/cloud-pubsub.png" alt="Pub/Sub" title="Pub/Sub"&gt;&lt;/a&gt;Pub/Sub&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pub/Sub&lt;/strong&gt; decouples publishers of events and subscribers to those events. Publishers do not need to know anything about their subscribers; the invocation is &lt;strong&gt;implicit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cloud Tasks is aimed at &lt;strong&gt;explicit&lt;/strong&gt; invocation where the publisher retains full control of execution. Particularly, the publisher specifies and endpoint where the message is to be delivered.&lt;/p&gt;

&lt;p&gt;In addition to this philosophical difference, Cloud Tasks provides the following mechanisms that aren't supported by Pub/Sub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scheduling specific delivery times&lt;/li&gt;
&lt;li&gt;Delivery rate controls&lt;/li&gt;
&lt;li&gt;Configurable retries&lt;/li&gt;
&lt;li&gt;Access and management of individual tasks in a queue&lt;/li&gt;
&lt;li&gt;Task/message creation deduplication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, Pub/Sub allows for the following which are not supported by Cloud Tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Batch insertion of messages&lt;/li&gt;
&lt;li&gt;Multiple handlers per message&lt;/li&gt;
&lt;li&gt;Max size of message is 10MB vs. 100KB in Cloud Tasks&lt;/li&gt;
&lt;li&gt;No upper limit to the delivery rate vs. limit of 500 qps/queue in Cloud Tasks&lt;/li&gt;
&lt;li&gt;Global availability vs. Regional availability in Cloud Tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See &lt;a href="https://cloud.google.com/tasks/docs/comp-pub-sub"&gt;Choosing between Cloud Tasks and Pub/Sub&lt;/a&gt; for a more detailed comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Tasks vs Cloud Scheduler
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DECyFl7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/cloud-scheduler.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DECyFl7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/managing-background-jobs-with-cloud-tasks/cloud-scheduler.png" alt="Cloud Scheduler" title="Cloud Scheduler"&gt;&lt;/a&gt;Cloud Scheduler&lt;/p&gt;

&lt;p&gt;The main difference is that Cloud Scheduler initiates actions on a fixed periodic schedule (cron), which Cloud Tasks initiates actions from a queue, which is usually populated from a user or service request.&lt;/p&gt;

&lt;p&gt;Cloud Scheduler does not retry a failed cron job, while Cloud Tasks retries a task until it succeeds.&lt;/p&gt;

&lt;p&gt;I like to use Cloud Scheduler to trigger a periodic job that creates a bunch of tasks in Cloud Tasks in one go, delegating rate-limit, concurrency, and retry handling to Cloud Tasks.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://cloud.google.com/tasks/docs/comp-tasks-sched"&gt;Cloud Tasks versus Cloud Scheduler&lt;/a&gt; for a more detailed comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Cloud Tasks is GCP's fully managed solution for handling queues of background jobs (tasks). It provides rate-limiting and retry capabilities that are not present in Pub/Sub. Before reaching out for Pub/Sub you may want to consider if Cloud Tasks suits your application's use case better.&lt;/p&gt;

&lt;p&gt;Cloud Tasks also provides a great alternative to third-party queues such as Resque or Sidekiq, if not better. Unlike these third-party queues, there are no workers or queues to manage; it is serverless apart from the task handlers which you will have to provide.&lt;/p&gt;

&lt;h2&gt;
  
  
  My GCP Books and Courses
&lt;/h2&gt;

&lt;p&gt;If you found this blog post helpful, kindly check out my &lt;a href="https://joncloudgeek.com/store/"&gt;books and courses on GCP&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>gcp</category>
      <category>cloudtasks</category>
      <category>queue</category>
    </item>
    <item>
      <title>What is Anthos by Google Cloud?</title>
      <dc:creator>Jonathan ES Lin</dc:creator>
      <pubDate>Mon, 08 Jun 2020 09:35:01 +0000</pubDate>
      <link>https://forem.com/ernsheong/what-is-anthos-by-google-cloud-5anb</link>
      <guid>https://forem.com/ernsheong/what-is-anthos-by-google-cloud-5anb</guid>
      <description>&lt;p&gt;This post was originally posted on &lt;a href="https://joncloudgeek.com/blog/what-is-anthos-by-google-cloud/" rel="noopener noreferrer"&gt;JonCloudGeek&lt;/a&gt; in Sep 2019. Details below may have changed in the meantime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Anthos Components&lt;/li&gt;
&lt;li&gt;Technicals&lt;/li&gt;
&lt;li&gt;Pricing&lt;/li&gt;
&lt;li&gt;The Good&lt;/li&gt;
&lt;li&gt;No new hardware necessary&lt;/li&gt;
&lt;li&gt;On-Premises&lt;/li&gt;
&lt;li&gt;Development and Operations&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;The Bad&lt;/li&gt;
&lt;li&gt;GKE vs Anthos Lines Blurred&lt;/li&gt;
&lt;li&gt;Cloud Run on GKE is no more?&lt;/li&gt;
&lt;li&gt;Binary Authorization, not available on GKE without Anthos?&lt;/li&gt;
&lt;li&gt;A bad sign for GKE and GCP&lt;/li&gt;
&lt;li&gt;Comparison with AWS and Azure offerings&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;li&gt;Related Links&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-is-anthos-by-google-cloud%2Fanthos-bridge-between-on-prem-and-gcp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-is-anthos-by-google-cloud%2Fanthos-bridge-between-on-prem-and-gcp.jpg" title="Anthos, the bridge between on-prem and Google Cloud." alt="Anthos, the bridge between on-prem and Google Cloud"&gt;&lt;/a&gt;Anthos, the bridge between on-prem and Google Cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It's no secret that Google Cloud is still catching up with AWS and Azure in terms of market share. &lt;a href="https://cloud.google.com/anthos/" rel="noopener noreferrer"&gt;Anthos&lt;/a&gt;, first announced at Google Cloud Next in April 2019, is Google Cloud's gambit to gain market share in the enterprise.&lt;/p&gt;

&lt;p&gt;Even as of this year, &lt;a href="https://www.ibm.com/blogs/cloud-computing/2019/03/05/20-percent-cloud-transformation/" rel="noopener noreferrer"&gt;80% of workloads are still on-premises&lt;/a&gt;. With Anthos, Google is hitting this need by giving enterprises a &lt;em&gt;uniform interface&lt;/em&gt; that abstracts away the complexity of deploying to on-premises and/or in the cloud.&lt;/p&gt;

&lt;p&gt;In other words, Anthos is &lt;a href="https://cloud.google.com/kubernetes-engine" rel="noopener noreferrer"&gt;Google Kubernetes Engine (GKE)&lt;/a&gt; deployed either on-premises or in the cloud (including third-party clouds like AWS and Azure). As far as enterprise developers are concerned, everything should be running on &lt;strong&gt;containers&lt;/strong&gt;, and where these containers end up at (on-premises or cloud) is just a matter of configuration on Anthos. It brings enterprises toward the utopia of write once, run anywhere, without learning diffirent environments and APIs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-is-anthos-by-google-cloud%2Fanthos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-is-anthos-by-google-cloud%2Fanthos.png" title="Anthos by Google Cloud" alt="Anthos by Google Cloud"&gt;&lt;/a&gt;Anthos by Google Cloud&lt;/p&gt;

&lt;h2&gt;
  
  
  Anthos Components
&lt;/h2&gt;

&lt;p&gt;Anthos is really a &lt;strong&gt;branding name for a collection of software components&lt;/strong&gt; rather than a piece of software by itself. Collectively, the components work together to achieve the above. Let's take a look at the components that make up Anthos (according to their &lt;a href="https://cloud.google.com/anthos/docs/components" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GKE On-Prem&lt;/strong&gt;. "GKE On-Prem is hybrid cloud software that brings Google Kubernetes Engine (GKE) to on-premises data centers. With GKE On-Prem, you can create, manage, and upgrade Kubernetes clusters in your on-prem environment and connect them to Google Cloud Platform Console." (&lt;a href="https://cloud.google.com/gke-on-prem/docs/overview" rel="noopener noreferrer"&gt;https://cloud.google.com/gke-on-prem/docs/overview&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GKE&lt;/strong&gt;. GKE is Google Cloud's managed Kubernetes offering. Given that Kubernetes originated from Google, GKE is arguably the best managed offering for Kubernetes out there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Migrate for Anthos&lt;/strong&gt;. "A tool to containerize existing applications to run on GKE." Basically a fancy name for scripts that help you generate Kubernetes yaml configs for your existing VMs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-cluster management overview&lt;/strong&gt;. A lacklustre name to represent a collection of tools to connect between your GKE On-Prem with other clusters on the Google Cloud Platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Anthos Config Management&lt;/strong&gt;. The one configuration to rule over Kubernetes clusters both on-premises and in the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Istio&lt;/strong&gt;. "Istio is an open platform to connect, secure, control, and monitor microservices." (&lt;a href="https://cloud.google.com/istio/docs/" rel="noopener noreferrer"&gt;https://cloud.google.com/istio/docs/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stackdriver&lt;/strong&gt;. Google Cloud's managed logging and monitoring solution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Run&lt;/strong&gt;. Deploy serverless containers. In the context of Anthos, you can deploy your serverless containers to GKE On-Prem or in the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kubernetes apps on GCP Marketplace&lt;/strong&gt;. You can even install Kubernetes containers found in GCP Marketplace to your GKE On-Prem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Traffic Director&lt;/strong&gt;. GCP's fully-managed traffic control plane for service meshes. This gives you an idea of what it does: "Traffic Director allows you to easily deploy global load balancing across clusters and VM instances in multiple regions and offload health checking from the sidecar proxies" (&lt;a href="https://cloud.google.com/traffic-director/docs/traffic-director-concepts" rel="noopener noreferrer"&gt;https://cloud.google.com/traffic-director/docs/traffic-director-concepts&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technicals
&lt;/h2&gt;

&lt;p&gt;GKE On-Prem requires a VMware vSphere environment, along with a layer 4 network load balancer.&lt;/p&gt;

&lt;p&gt;As for site-to-site connection between on-premises and cloud, the options are either Cloud VPN, Dedicated Interconnect or Partner Interconnect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;p&gt;Here's where we get into the juicier parts of the discussion. The &lt;a href="https://cloud.google.com/anthos/pricing/" rel="noopener noreferrer"&gt;Anthos Pricing page&lt;/a&gt; redirects to "Contact sales". That implies $$$$.&lt;/p&gt;

&lt;p&gt;However, in &lt;a href="https://cloud.google.com/anthos/docs/faq/" rel="noopener noreferrer"&gt;Anthos FAQ&lt;/a&gt;, we get an indication of the pricing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anthos will be available to enterprises via a term-based monthly subscription, entitling users to ongoing updates and security patches across hybrid environments.&lt;/p&gt;

&lt;p&gt;Anthos can be purchased in blocks of 100 vCPUs requiring a minimum one year term (at $100 per vCPU/month). These vCPUs can be allocated in any combination across environments. Please contact sales for pricing.&lt;/p&gt;

&lt;p&gt;The pricing listed above is in addition to core infrastructure charges including, but not limited to CPU, networking, infrastructure support, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, it starts from &lt;strong&gt;$10,000 per month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There's a problem with that. I think that even the largest of Malaysian enterprises would not want to spend RM45,000/month on something like this. The target market for Anthos is not just enterprise, but enterprise with a big E, for which $10,000/month is pocket change. Think the likes of HSBC, which Google shows off as an early customer in the &lt;a href="https://cloud.google.com/blog/topics/hybrid-cloud/new-platform-for-managing-applications-in-todays-multi-cloud-world" rel="noopener noreferrer"&gt;Anthos launch blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Good
&lt;/h2&gt;

&lt;p&gt;The promise of Anthos sounds compelling, but I can't speak on behalf of Enterprise.&lt;/p&gt;

&lt;h3&gt;
  
  
  No new hardware necessary
&lt;/h3&gt;

&lt;p&gt;Anthos is a software solution. Companies do not need to buy hardware from Google in order to leverage Anthos. They can start with their existing on-premises machines.&lt;/p&gt;

&lt;h3&gt;
  
  
  On-Premises
&lt;/h3&gt;

&lt;p&gt;Writing once and running it anywhere you choose, here today, there tomorrow, and back here again the day after, is now possible with Anthos. Enterprises can plan out their timelines for gradual migration to the cloud, while maintaining the ability to keep workloads on-premises for compliance and other reasons.&lt;/p&gt;

&lt;p&gt;And they can now do all this using the cutting-edge managed Kubernetes offering from Google, with Istio and other bells and whistles, while maintaining presence on-premises. It's an enterprise's dream, perhaps?&lt;/p&gt;

&lt;h3&gt;
  
  
  Development and Operations
&lt;/h3&gt;

&lt;p&gt;Developers get to run GKE on-premises. Operations gets a single unified dashboard and configuration for their applications, not to mention a whole lot less work mitigating server problems given that Kubernetes is more robust and has self-healing and auto-scaling capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;Anthos Config Management allows centralized cluster configuration. Istio provides code-free securing of microservices.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bad
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GKE vs Anthos Lines Blurred
&lt;/h3&gt;

&lt;p&gt;Over the past few weeks the lines between what is GKE and what is Anthos have blurred. It seems that some parts of GKE have been absorbed into Anthos and placed behind the Anthos paywall, such as the examples shown below. I believe that at this stage, GCP is still trying to figure out the exact pricing of GKE add-ons for non-Anthos users, but it could also be the case that GCP effectively draws a strict line between vanilla GKE and Anthos-branded GKE add-ons, requiring payment to use the latter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud Run on GKE is no more?
&lt;/h3&gt;


&lt;blockquote&gt;
&lt;p&gt;What's the verdict now? Lay devs can't run Cloud Run in their own GKE cluster without an Anthos subscription? Not sure if many are affected, but the choice was nice to have, and now gone?&lt;/p&gt;— Jonathan Lin 👨🏻‍💻🇲🇾 (&lt;a class="mentioned-user" href="https://dev.to/ernsheong"&gt;@ernsheong&lt;/a&gt;) &lt;a href="https://twitter.com/ernsheong/status/1177415240092241921?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;September 27, 2019&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;When Cloud Run was announced, it had an option in the Console to deploy to "Cloud Run on GKE". Today, it just says "Cloud Run for Anthos". Cloud Run is in Beta, so Google has the right to make such changes, but the trend seems to be making the add-on features of GKE a part of Anthos, which presumably requires a subscription of some sort (this is unclear in the documentation).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-is-anthos-by-google-cloud%2Fcloud-run-for-anthos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-is-anthos-by-google-cloud%2Fcloud-run-for-anthos.png" title="You must have Cloud Run for Anthos enabled in your cluster. Do I have to pay for that?" alt="Cloud Run for Anthos"&gt;&lt;/a&gt;You must have Cloud Run for Anthos enabled in your cluster. Do I have to pay for that?&lt;/p&gt;

&lt;h3&gt;
  
  
  Binary Authorization, not available on GKE without Anthos?
&lt;/h3&gt;

&lt;p&gt;With &lt;a href="https://cloud.google.com/binary-authorization/" rel="noopener noreferrer"&gt;Binary Authorization&lt;/a&gt;, images are to be signed by trusted authorities during development, and these signatures are validated on deployment. This was touted as a security feature at a local Cloud Summit event recently. But it seems clear right now that this feature will only be part of an Anthos subscription:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The General Availability (GA) version of Binary Authorization is a feature of the Anthos platform. Use of Binary Authorization is included in the Anthos subscription. Please contact your sales representative to enroll in Anthos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  A bad sign for GKE and GCP
&lt;/h3&gt;

&lt;p&gt;All these does not harbinger well for GKE itself. Google wants to reach out to the Enterprise, but it should &lt;em&gt;not&lt;/em&gt; alienate non-Enterprise users who are already champions of GKE as the best managed Kubernetes offering. Granted, you can't really make everyone happy all the time, but taking away or limiting features from the vanilla GKE core is a bad taste that makes us think twice about recommended GKE to others.&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;GCP is treading dangerously. IMO, purely-GKE customers (no on-prem) should not be subject to the “Anthos tax”. Withholding features in Anthos from purely-GKE customers is a slippery slope that might backfire as people realize GKE itself is handicapped on purpose.&lt;/p&gt;— Jonathan Lin 👨🏻‍💻🇲🇾 (&lt;a class="mentioned-user" href="https://dev.to/ernsheong"&gt;@ernsheong&lt;/a&gt;) &lt;a href="https://twitter.com/ernsheong/status/1177455606589878272?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;September 27, 2019&lt;/a&gt;
&lt;/blockquote&gt; 
&lt;h2&gt;
  
  
  Comparison with AWS and Azure offerings
&lt;/h2&gt;

&lt;p&gt;From what I gather, the VMware vSphere requirement plays well with existing setups on-premises. In other words, customers would not need to purchase new hardware in order to leverage Anthos.&lt;/p&gt;

&lt;p&gt;In contrast, &lt;a href="https://aws.amazon.com/outposts/" rel="noopener noreferrer"&gt;AWS Outposts&lt;/a&gt; and &lt;a href="https://azure.microsoft.com/en-us/overview/azure-stack/" rel="noopener noreferrer"&gt;Azure Stack&lt;/a&gt; require you to purchase hardware from AWS or Azure in order to leverage their hybrid cloud solutions.&lt;/p&gt;

&lt;p&gt;AWS Outposts &lt;a href="https://aws.amazon.com/outposts/faqs/" rel="noopener noreferrer"&gt;FAQs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Q: Can I reuse my existing servers in an Outpost?&lt;/p&gt;

&lt;p&gt;A: No, AWS Outposts leverages AWS designed infrastructure, and is only supported on proprietary AWS hardware that is optimized for secure, high-performance, and reliable operations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Azure Stack - &lt;a href="https://azure.microsoft.com/en-us/overview/azure-stack/how-to-buy/" rel="noopener noreferrer"&gt;How to Buy&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure Stack is sold as an integrated hardware system, with software pre-installed on validated hardware.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, it seems that with AWS Outposts and Azure Stack you can use many more service offerings from AWS and Azure, whilst with Anthos you are limited to basically GKE On-Prem and GKE itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Anthos is Google Cloud's gambit to lure enterprises to use Google Cloud with a single consistent interface for application deployment to both on-premises or in the cloud. Google Cloud is betting that containers will be king in the enterprise world. If Google plays it right, the rewards via Anthos will be great, and Anthos has the potential to be the Trojan Horse of the cloud wars.&lt;/p&gt;

&lt;p&gt;At the same time, with Anthos, Google Cloud risks alienating users of GKE by withholding Anthos-only features from GKE users. GKE is one of Google Cloud's strongest offerings. Google Cloud should not handicap GKE in other to hide features behind Anthos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What’s Going on with GKE and Anthos? &lt;a href="https://bravenewgeek.com/whats-going-on-with-gke-and-anthos/" rel="noopener noreferrer"&gt;https://bravenewgeek.com/whats-going-on-with-gke-and-anthos/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Everything You Want To Know About Anthos - Google's Hybrid And Multi-Cloud Platform &lt;a href="https://www.forbes.com/sites/janakirammsv/2019/04/14/everything-you-want-to-know-about-anthos-googles-hybrid-and-multi-cloud-platform/" rel="noopener noreferrer"&gt;https://www.forbes.com/sites/janakirammsv/2019/04/14/everything-you-want-to-know-about-anthos-googles-hybrid-and-multi-cloud-platform/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How Google’s Anthos Is Different from AWS and Azure Hybrid Clouds &lt;a href="https://www.datacenterknowledge.com/google-alphabet/how-google-s-anthos-different-aws-and-azure-hybrid-clouds" rel="noopener noreferrer"&gt;https://www.datacenterknowledge.com/google-alphabet/how-google-s-anthos-different-aws-and-azure-hybrid-clouds&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Introducing Anthos: An entirely new platform for managing applications in today's multi-cloud world &lt;a href="https://cloud.google.com/blog/topics/hybrid-cloud/new-platform-for-managing-applications-in-todays-multi-cloud-world" rel="noopener noreferrer"&gt;https://cloud.google.com/blog/topics/hybrid-cloud/new-platform-for-managing-applications-in-todays-multi-cloud-world&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anthos simplifies application modernization with managed service mesh and serverless for your hybrid cloud &lt;a href="https://cloud.google.com/blog/topics/hybrid-cloud/anthos-simplifies-application-modernization-with-managed-service-mesh-and-serverless-for-your-hybrid-cloud" rel="noopener noreferrer"&gt;https://cloud.google.com/blog/topics/hybrid-cloud/anthos-simplifies-application-modernization-with-managed-service-mesh-and-serverless-for-your-hybrid-cloud&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My GCP Books
&lt;/h2&gt;

&lt;p&gt;If you found this blog post helpful, kindly check out my &lt;a href="https://joncloudgeek.com/books/" rel="noopener noreferrer"&gt;books on GCP topics&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>gcp</category>
      <category>anthos</category>
    </item>
    <item>
      <title>What Cloud Native Is and Isn't</title>
      <dc:creator>Jonathan ES Lin</dc:creator>
      <pubDate>Mon, 08 Jun 2020 08:36:59 +0000</pubDate>
      <link>https://forem.com/ernsheong/what-cloud-native-is-and-isn-t-2ii</link>
      <guid>https://forem.com/ernsheong/what-cloud-native-is-and-isn-t-2ii</guid>
      <description>&lt;p&gt;This post was originally posted on &lt;a href="https://joncloudgeek.com/blog/what-cloud-native-is-and-isnt/" rel="noopener noreferrer"&gt;JonCloudGeek&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Citizen-Country Analogy&lt;/li&gt;
&lt;li&gt;Official definition?&lt;/li&gt;
&lt;li&gt;What Cloud Native &lt;em&gt;Isn't&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;What Cloud Native &lt;em&gt;Is&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;What Cloud Native Infrastructure &lt;em&gt;Is&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;What Cloud Native Applications &lt;em&gt;Are&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;li&gt;Related Links&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fhigh-performance-in-cloud.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fhigh-performance-in-cloud.jpg" title="High performance applications in the cloud." alt="Fighter jets in the sky"&gt;&lt;/a&gt;High performance applications in the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cloud native&lt;/strong&gt; is a phrase we are beginning to hear more and more in recent days. From a language standpoint, "cloud native" seems to imply that some applications do not fit very well in the cloud (like a tourist in a foreign land), while other &lt;em&gt;cloud native applications&lt;/em&gt; are very much at home and thriving in the cloud (like a citizen of a country). In fact, &lt;em&gt;cloud native applications&lt;/em&gt; (citizens) are most at home in &lt;em&gt;cloud native infrastructures&lt;/em&gt; (countries).&lt;/p&gt;

&lt;h2&gt;
  
  
  Citizen-Country Analogy
&lt;/h2&gt;

&lt;p&gt;Let's stretch this citizen-country analogy a bit further. There are many countries, and many citizens who, in most cases, belong to only one particular country. Not all countries are the same, though generally they share certain characteristics that make them a country: flag, immigration, government, shared culture/language. Likewise there are probably many ways to do &lt;em&gt;&lt;strong&gt;cloud native infrastructure&lt;/strong&gt;&lt;/em&gt;, and while there may be differences in implementation and details, they share the same distinctive set of characteristics and principles.&lt;/p&gt;

&lt;p&gt;Secondly, a citizen of a particular country may visit another country and live there for many years. However, even after being in another country for a decade, that citizen would probably still say that he is more at home in his home country, and able to better take advantage of the benefits of citizenship that are bestowed to him at home. Likewise, a particular &lt;strong&gt;&lt;em&gt;cloud native application&lt;/em&gt;&lt;/strong&gt; is always written in such a way that the application is more at home and &lt;em&gt;able to take fuller advantage of the infrastructure&lt;/em&gt; in a certain &lt;em&gt;native&lt;/em&gt; infrastructure than in another infrastructure.&lt;/p&gt;

&lt;p&gt;In essence, when we talk about cloud native, we need to address what it means for both &lt;strong&gt;infrastructure&lt;/strong&gt; and &lt;strong&gt;applications&lt;/strong&gt; to be cloud native.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official definition?
&lt;/h2&gt;

&lt;p&gt;There is actually a foundation called the &lt;strong&gt;Cloud Native Computing Foundation (CNCF)&lt;/strong&gt; that champions cloud native technologies to "enable cloud portability without vendor lock-in" (&lt;a href="https://www.cncf.io/about/faq/" rel="noopener noreferrer"&gt;CNCF FAQ&lt;/a&gt;). Its mission is "to make cloud native computing ubiquitous."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fcncf-logo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fcncf-logo.png" title="Cloud Native Computing Foundation (CNCF)" alt="CNCF Logo"&gt;&lt;/a&gt;Cloud Native Computing Foundation (CNCF)&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/cncf/toc/blob/master/DEFINITION.md" rel="noopener noreferrer"&gt;CNCF Cloud Native Definition v*0&lt;/a&gt; says (words in bold are mine for emphasis):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cloud native technologies empower organizations to build and run &lt;strong&gt;scalable applications&lt;/strong&gt; in modern, dynamic environments such as &lt;strong&gt;public, private, and hybrid clouds&lt;/strong&gt;. &lt;strong&gt;Containers, service meshes, microservices, immutable infrastructure, and declarative APIs&lt;/strong&gt; exemplify this approach.&lt;/p&gt;

&lt;p&gt;These techniques enable &lt;strong&gt;loosely coupled systems&lt;/strong&gt; that are &lt;strong&gt;resilient, manageable, and observable&lt;/strong&gt;. Combined with robust &lt;strong&gt;automation&lt;/strong&gt;, they allow engineers to make high-impact changes frequently and predictably with minimal toil.&lt;/p&gt;

&lt;p&gt;The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of &lt;strong&gt;open source, vendor-neutral projects&lt;/strong&gt;. We democratize state-of-the-art patterns to make these innovations accessible for everyone.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think the "official definition" is helpful to us to clarify what cloud native is and isn't. Let's take a look at what traits are non-negotiable from this definition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Non-negotiable&lt;/strong&gt;: Scalable applications, public/private/hybrid clouds, loosely coupled systems, resilient &amp;amp; manageable &amp;amp; observable, automation, open-source &amp;amp; vendor-neutral&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Negotiable&lt;/strong&gt;: Containers, service meshes, microservices, immutable infrastructure, declaractive APIs (although these are "exemplary")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fcncf-platinum.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fcncf-platinum.png" title="CNCF Platinum Members (Source: CNCF Website)" alt="CNCF Platinum Members"&gt;&lt;/a&gt;CNCF Platinum Members (Source: CNCF Website)&lt;/p&gt;

&lt;p&gt;Many of the points that follow borrow heavily from many of the points made from  Chapter 1 of the book, &lt;em&gt;Cloud Native Infrastructure&lt;/em&gt;, by Kris Nova and Justin Garrison, which can be found &lt;a href="https://www.oreilly.com/library/view/cloud-native-infrastructure/9781491984291/ch0*html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Cloud Native &lt;em&gt;Isn't&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;It is often instructive, when trying to understand a complex subject, to first start off by exploring what the subject &lt;em&gt;isn't&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native isn't just about running applications in a public cloud&lt;/strong&gt;. After all, you could simply "lift and shift" VMs from your own datacenter to EC2 or Compute Engine in the cloud (infrastructure-as-a-service), and virtually nothing was gained from it  .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native is not about running applications in containers&lt;/strong&gt;. For instance, running applications in containers per se (e.g. via &lt;code&gt;docker run&lt;/code&gt;) is not really that much of a gain compared to running the application straight in the VM itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native doesn't mean you only run a container orchestrator&lt;/strong&gt;, e.g. Kubernetes. After all, it is possible to use a container orchestrator in a way that is not intended, locking in applications to a specific set of servers. It &lt;em&gt;is&lt;/em&gt;, however, a big step forward in the right direction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native is not about microservices&lt;/strong&gt;. While microservices have benefits such as allowing shorter development cycles on a smaller feature set, monolithic applications can also have the same benefits when done properly, and can also benefit from cloud native infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native is not about infrastructure as code&lt;/strong&gt;. Infrastructure as code, such as Ansible, Chef, and Puppet, automates infrastructure in a particular domain-specific language (DSL). However, using these tools often merely automate one server at a time, and do not actually manage applications better.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Cloud Native &lt;em&gt;Is&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Since cloud native applications and cloud native infrastructure are separate but related concerns, I'll discuss them separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Cloud Native Infrastructure &lt;em&gt;Is&lt;/em&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native infrastructure is hidden behind useful abstractions&lt;/strong&gt;. There would not really be a "cloud" if all you get is access to bare metal APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native infrastructure is controlled by APIs&lt;/strong&gt;. As above, the abstractions are to be provided for via an API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native infrastructure is managed by software&lt;/strong&gt;. Cloud native infrastructure is not user-managed, it is self-managing by software.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native infrastructure is optimized for running applications&lt;/strong&gt;. The chief aim of cloud native infrastructure is to run applications for the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, cloud native infrastructure behaves very much like a platform-as-a-service (PaaS) offering.&lt;/p&gt;

&lt;p&gt;While the CNCF would like to advocate for "open-source" and "vendor-neutral" solutions as its definition of cloud native (see above), I think that such a definition would preclude what many in industry already consider to be cloud native. Examples of this are AWS Lambda, AWS Elastic Container Service (ECS), AWS Fargate, which are all decidedly proprietary with no open source equivalents, but many still consider them to be cloud native. Hence I think the list is a good guiding principle on what is cloud native in general.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt; is the poster child of cloud native infrastructure which checks all the boxes above while being open-source and vendor neutral. However, we would be very wrong to conclude that Kubernetes is the only way to having a cloud native infrastructure. In fact, I would even dare to say that trying to manage your own Kubernetes is not in line with the principles of cloud native, because in many ways you are managing it &lt;em&gt;yourself&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fkubernetes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjoncloudgeek.com%2Fblog%2Fwhat-cloud-native-is-and-isnt%2Fkubernetes.png" title="Kubernetes" alt="Kubernetes logo"&gt;&lt;/a&gt;Kubernetes&lt;/p&gt;

&lt;h3&gt;
  
  
  What Cloud Native Applications &lt;em&gt;Are&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A cloud native application is designed to run on a cloud native infrastructure platform with the following four key traits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native applications are resilient&lt;/strong&gt;. &lt;em&gt;Resiliency&lt;/em&gt; is achieved when failures are treated as the norm rather than something to be avoided. The application takes advantage of the dynamic nature of the platform and should be able to recover from failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native applications are agile&lt;/strong&gt;. &lt;em&gt;Agility&lt;/em&gt; allows the application to be deployed quickly with short iterations. Often this requires applications to be written as microservices rather than monoliths, but having microservices is not a requirement for cloud native applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native applications are operable&lt;/strong&gt;. &lt;em&gt;Operability&lt;/em&gt; concerns itself with the qualities of a system that make it work well over its lifetime, not just at deployment phase. An operable application is not only reliable from the end-user point of view, but also from the vantage of the operations team. Examples of operable software is one which operates without needing application restarts or server reboots, or hacks and workarounds that are required to keep the software running. Often this means that the application itself should expose a health check in order for the infrastructure it is running on to query the state of the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud native applications are observable&lt;/strong&gt;. &lt;em&gt;Observability&lt;/em&gt; provides answers to questions about application state. Operators and engineers should not need to make conjectures about what is going on in the application. Application logging and metrics are key to making this happen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above list suggests that cloud native applications impact the infrastructure that would be necessary to run such applications. Many responsibilities that have been traditionally handled by infrastructure have moved into the  application realm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Cloud native is a loaded term which is easily misused by many marketing departments. Everyone claims that their infrastructure solutions are cloud native, but I believe that a guiding rule of thumb (in line with everything that has been mentioned above) is that being cloud native should enable your organization to leverage cloud infrastructure in a way that is &lt;strong&gt;cost-effective&lt;/strong&gt; and &lt;strong&gt;resource-effective&lt;/strong&gt;, that is to say, waste and spend as little (time, effort, and money) as possible while achieving more optimum and faster results, &lt;em&gt;compared to the most optimal state and performance that today's technology allows&lt;/em&gt;; it is a continuum rather than a binary state. In my view, that is really what it means to be cloud native.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cloud Native Infrastructure (Chapter 1) &lt;a href="https://www.oreilly.com/library/view/cloud-native-infrastructure/9781491984291/ch0*html" rel="noopener noreferrer"&gt;https://www.oreilly.com/library/view/cloud-native-infrastructure/9781491984291/ch0*html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;What is Operability? &lt;a href="https://blog.softwareoperability.com/what-is-operability/" rel="noopener noreferrer"&gt;https://blog.softwareoperability.com/what-is-operability/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My GCP Books
&lt;/h2&gt;

&lt;p&gt;If you found this blog post helpful, kindly check out my &lt;a href="https://joncloudgeek.com/books/" rel="noopener noreferrer"&gt;books on GCP topics&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>cloud</category>
    </item>
    <item>
      <title>Run a Postgres instance for cheap in Google Cloud</title>
      <dc:creator>Jonathan ES Lin</dc:creator>
      <pubDate>Mon, 25 May 2020 10:42:55 +0000</pubDate>
      <link>https://forem.com/ernsheong/run-a-postgres-instance-for-cheap-in-google-cloud-55om</link>
      <guid>https://forem.com/ernsheong/run-a-postgres-instance-for-cheap-in-google-cloud-55om</guid>
      <description>&lt;p&gt;This post was originally posted on &lt;a href="https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/"&gt;JonCloudGeek&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Scenario&lt;/li&gt;
&lt;li&gt;Get started&lt;/li&gt;
&lt;li&gt;Create a compute instance running a Postgres container&lt;/li&gt;
&lt;li&gt;Add a Firewall rule to connect to this instance&lt;/li&gt;
&lt;li&gt;Migrate data to new DB&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;li&gt;Disclaimer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eUzG5EP8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/meta.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eUzG5EP8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/meta.jpg" alt="An elephant" title="Postgres in a container"&gt;&lt;/a&gt;Postgres in a container&lt;/p&gt;

&lt;p&gt;In this blog post, I will explore running a Postgres instance in a container within Compute Engine for a fraction of what it costs to run in Cloud SQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cloud.google.com/sql"&gt;Cloud SQL&lt;/a&gt; is kind of expensive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;f1-micro&lt;/code&gt; gives you a weak instance with only 0.25 vCPU burstable to 1 vCPU, from $9.37.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;g1-small&lt;/code&gt; is still 0.5 vCPU burstable to 1 vCPU, but the price jumps to from $27.25.&lt;/li&gt;
&lt;li&gt;Let's not even talk about the non-shared vCPU standard instances.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For toy project or production projects that just don't need that power, Cloud SQL is overkill, at least the price is overkill.&lt;/p&gt;

&lt;p&gt;This blog post is for smaller projects that need Postgres but without Cloud SQL, and without the maintenance hassle of running commands to manually install Postgres.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sign up for &lt;a href="https://console.cloud.google.com/"&gt;Google Cloud&lt;/a&gt;. Free trial gives you $300 credits lasting one year.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project"&gt;Create a project&lt;/a&gt; to house your related resources.&lt;/li&gt;
&lt;li&gt;Navigate to &lt;a href="https://console.cloud.google.com/compute/instances"&gt;Compute Engine&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create a compute instance running a Postgres container
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;In the Compute Engine instances page in the Cloud Console, click on &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a8KG2HHA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/click-create.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a8KG2HHA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/click-create.png" alt="Click on Create" title="Click Create"&gt;&lt;/a&gt;Click Create&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the E2 series and the &lt;code&gt;e2-micro&lt;/code&gt; machine type. E2 series is a cost-optimized series of compute engine instances. Read more about it in the &lt;a href="https://cloud.google.com/blog/products/compute/google-compute-engine-gets-new-e2-vm-machine-types"&gt;launch blog post&lt;/a&gt;. &lt;code&gt;e2-micro&lt;/code&gt; is like &lt;code&gt;f1-micro&lt;/code&gt;, but with &lt;strong&gt;2 shared vCPU&lt;/strong&gt;, which is good enough for almost any small project, but not compromising like the weak &lt;code&gt;f1-micro&lt;/code&gt; (which hangs / throttles when you try to do too much CPU work).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;e2-micro&lt;/code&gt; starts from &lt;strong&gt;$6.11/month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BfyzOXNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/select-e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BfyzOXNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/select-e2.png" alt="Select e2-micro" title="Select e2-micro"&gt;&lt;/a&gt;Select e2-micro&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check &lt;strong&gt;Deploy a container image to this VM instance&lt;/strong&gt;. This will cause Compute Engine to only run the given image (next step) in the compute instance. Each compute instance can only run a single container using this method, and since we have sized our instance to only have just enough resources, this is totally fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lHP0n2yz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/check-container.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lHP0n2yz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/check-container.png" alt="Check Deploy a container image to this VM instance" title="Check this to deploy a container image to our Compute Engine instance"&gt;&lt;/a&gt;Check this to deploy a container image to our Compute Engine instance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose a Postgres image from the Marketplace.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Search for Postgres in Marketplace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bp2DvMXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/marketplace-postgres-search.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bp2DvMXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/marketplace-postgres-search.png" alt="Search for Postgres in Marketplace" title="Search for Postgres in Marketplace"&gt;&lt;/a&gt;Search for Postgres in Marketplace&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select a Postgres version:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--840mbE04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/marketplace-postgres-results.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--840mbE04--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/marketplace-postgres-results.png" alt="Choose your desired Postgres version" title="Choose your desired Postgres version"&gt;&lt;/a&gt;Choose your desired Postgres version&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on &lt;strong&gt;Show Pull Command&lt;/strong&gt; to retrieve the image URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CYxGsMd6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/show-pull-command.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CYxGsMd6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/show-pull-command.png" alt="Click on Show Pull Command" title="Click on Show Pull Command"&gt;&lt;/a&gt;Click on Show Pull Command&lt;/p&gt;

&lt;p&gt;If you click on &lt;strong&gt;Get Started with Postgresql 11&lt;/strong&gt; it will bring you to a Github page with more (important) information.&lt;/p&gt;

&lt;p&gt;Notably you want to take note of the list of &lt;a href="https://github.com/GoogleCloudPlatform/postgresql-docker/blob/master/11/README.md#environment-variables"&gt;Environment Variables&lt;/a&gt; understood by the container image.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy the image URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q4mLvrGm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/copy-image-url.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q4mLvrGm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/copy-image-url.png" alt="Copy the image url" title="Copy the image url"&gt;&lt;/a&gt;Copy the image url&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Paste the image URL into previous Compute Engine step. Set the minimum necessary environment variables. The default user is &lt;strong&gt;postgres&lt;/strong&gt;. POSTGRES_DB is arguably unnecessary, you can already create it manually after instance creation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--isG7f5MG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/set-image-env-var.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--isG7f5MG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/set-image-env-var.png" alt="Set the image and environment variables" title="Set the image and environment variables"&gt;&lt;/a&gt;Set the image and environment variables&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;[VERY IMPORTANT]&lt;/strong&gt; Mount a directory and point it at where the container stores data. &lt;strong&gt;IF YOU DO NOT DO THIS, WHEN YOUR INSTANCE REBOOTS OR STOPS FOR WHATEVER REASON, ALL DATA DISAPPEARS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RCwWI7sW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/mount-volume.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RCwWI7sW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/mount-volume.png" alt="Mount a volume at the Postgres data directory" title="Mount a volume at the Postgres data directory"&gt;&lt;/a&gt;Mount a volume at the Postgres data directory&lt;/p&gt;

&lt;p&gt;It is somewhat container intuitive, usually in the command line we state the host path first, and then the mount path. Here &lt;strong&gt;Mount path&lt;/strong&gt; (the container directory) comes first, and &lt;strong&gt;Host path&lt;/strong&gt; (the OS directory) comes second.&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Done&lt;/strong&gt;.&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Some optional settings to configure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ovUNj-H9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/secure-boot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ovUNj-H9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/secure-boot.png" alt="Turn on Secure Boot" title="Turn on Secure Boot"&gt;&lt;/a&gt;Turn on Secure Boot&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Se5OWiNN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/uncheck-delete-boot-disk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Se5OWiNN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/uncheck-delete-boot-disk.png" alt="Uncheck Delete boot disk when instance is deleted" title="Uncheck Delete boot disk when instance is deleted"&gt;&lt;/a&gt;Uncheck Delete boot disk when instance is deleted&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Add a Firewall rule to connect to this instance
&lt;/h2&gt;

&lt;p&gt;By default, post 5432 is blocked in a Google Cloud project. To allow connections from your local machine, do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;strong&gt;Firewall rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0O5TgH3X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/search-firewall.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0O5TgH3X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/search-firewall.png" alt="Search for firewall and click on Firewall rules (VPC network)" title="Search for firewall and click on Firewall rules (VPC network)"&gt;&lt;/a&gt;Search for firewall and click on Firewall rules (VPC network)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Create Firewall Rule&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Name, &lt;strong&gt;allow-postgres&lt;/strong&gt; (or anything you like)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Target tags&lt;/strong&gt;, add &lt;code&gt;allow-postgres&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Source IP ranges&lt;/strong&gt;, add &lt;code&gt;0.0.0.0/0&lt;/code&gt;. Or Google "my ip" and paste in the result (safer but cumbersome, IP changes frequently).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Specific protocols and ports&lt;/strong&gt;, add &lt;code&gt;5432&lt;/code&gt; in &lt;strong&gt;tcp&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go back to the DB instance, click &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the &lt;code&gt;allow-postgres&lt;/code&gt; network tag:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P_MSr-IK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/add-network-tag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P_MSr-IK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/add-network-tag.png" alt="Add the allow-postgres network tag" title="Add the allow-postgres network tag"&gt;&lt;/a&gt;Add the allow-postgres network tag&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Save&lt;/strong&gt;. Your instance is now accessible from your local machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Migrate data to new DB
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Dump your current DB data:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump &lt;span class="nt"&gt;-d&lt;/span&gt; mydb &lt;span class="nt"&gt;-h&lt;/span&gt; db.example.com &lt;span class="nt"&gt;-U&lt;/span&gt; myuser &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;plain &lt;span class="nt"&gt;--no-owner&lt;/span&gt; &lt;span class="nt"&gt;--no-acl&lt;/span&gt;  &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'s/(DROP|CREATE|COMMENT ON) EXTENSION/-- \1 EXTENSION/g'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; mydb-dump.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Get the external IP of our new DB:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CTRZjYrM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/get-external-ip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CTRZjYrM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/get-external-ip.png" alt="Copy the external IP of the new instance" title="Copy the external IP of the new instance"&gt;&lt;/a&gt;Copy the external IP of the new instance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the external IP to &lt;code&gt;psql&lt;/code&gt; to the instance. When prompted, paste the DB password from &lt;code&gt;POSTGRES_PASSWORD&lt;/code&gt; earlier. The following command restores the dump back into the new DB instance:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;EXTERNAL_IP] &lt;span class="nt"&gt;-U&lt;/span&gt; postgres mydb &amp;lt; mydb-dump.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your DB is now ready. When creating the DB, note the internal hostname for this instance:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xrG0i6yC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/note-hostname.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xrG0i6yC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joncloudgeek.com/blog/deploy-postgres-container-to-compute-engine/note-hostname.png" alt="Note the instance internal hostname" title="Note the instance internal hostname"&gt;&lt;/a&gt;Note the instance internal hostname&lt;/p&gt;

&lt;p&gt;You can use this internal hostname to talk to this DB from within your VPC (another Compute Engine instance, Cloud Run, GKE, etc.). If that fails, then you can fallback to the &lt;strong&gt;Internal IP&lt;/strong&gt; (see screenshot in Step 2).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;[HIGHLY RECOMMENDED]&lt;/strong&gt; Stop (shut down) your DB instance and start it again. Connect to your instance via &lt;code&gt;psql&lt;/code&gt; (note that the External IP will likely change). Check that all your data is intact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove &lt;code&gt;allow-postgres&lt;/code&gt; from your instance &lt;strong&gt;Network tags&lt;/strong&gt; (Edit, remove, Save). Your instance is no longer publicly accessible. By default, all internal network ports are open in Firewall rules so your DB instance remains accessible from within your VPC.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this blog post, we have successfully created a Postgres instance from a container image in Compute Engine. We configured a firewall rule to connect to that instance from our local machine using a network tag, and we removed that network tag to lock up access to that instance. We also used the instance External IP to connect to it and restore dumped SQL data from our old instance (with the firewall rule in place).&lt;/p&gt;

&lt;p&gt;If you are confident about the needs and performance of your application, you can choose to downgrade the instance to &lt;code&gt;f1-micro&lt;/code&gt; to save another $2/month. Eventually GCP will come along and tell you that your instance is over-utilized (you can ignore or reject the warning). Note that all the risk is yours if your DB instance hangs because it is CPU-starved. There is an increased risk to cheap in the cloud.&lt;/p&gt;

&lt;p&gt;Alternatively, there is a Postgres &lt;a href="https://console.cloud.google.com/marketplace/details/click-to-deploy-images/postgresql"&gt;&lt;strong&gt;Google Click to Deploy&lt;/strong&gt;&lt;/a&gt; option in the Marketplace. This will run Postgres in Debian OS, not a container. And you also cannot run it in an E2 instance (only N1 is supported). But it is probably more production ready, I presume.&lt;/p&gt;

&lt;p&gt;Also highly recommended is that you take &lt;a href="https://cloud.google.com/compute/docs/disks/scheduled-snapshots"&gt;&lt;strong&gt;scheduled snapshots&lt;/strong&gt;&lt;/a&gt; of the boot disk of the DB instance. This is important for data recovery and backups. Usually Cloud SQL takes care of this for you, but we need to handle it ourselves since we are DIY-ing here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;The information provided in this blog post is provided as is, without warranty of any kind, express or implied. By following the steps outlined in this blog post I do not guarantee that your database will be free from any sort of failures or data losses.&lt;/p&gt;

&lt;h2&gt;
  
  
  My GCP Books
&lt;/h2&gt;

&lt;p&gt;If you found this blog post helpful, kindly check out my &lt;a href="https://joncloudgeek.com/books/"&gt;books on GCP topics&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>gcp</category>
      <category>postgres</category>
      <category>computeengine</category>
    </item>
  </channel>
</rss>
