<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Colan Schwartz on Cloud Architecture, Security, Privacy &amp; Startups</title>
        <link>https://colan.pro/</link>
        <description>Recent content on Colan Schwartz on Cloud Architecture, Security, Privacy &amp; Startups</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-ca</language>
        <copyright>8494959 Canada Inc.</copyright>
        <lastBuildDate>Sat, 13 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://colan.pro/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Forfeiting the Frontier: How Washington Is Ceding Its Own AI Advantage</title>
        <link>https://colan.pro/blog/forfeiting-the-frontier-how-washington-is-ceding-its-own-ai-advantage/</link>
        <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/forfeiting-the-frontier-how-washington-is-ceding-its-own-ai-advantage/</guid>
        <description>&lt;img src="https://colan.pro/blog/forfeiting-the-frontier-how-washington-is-ceding-its-own-ai-advantage/forfeiting-the-frontier-how-washington-is-ceding-its-own-ai-advantage.png" alt="Featured image of post Forfeiting the Frontier: How Washington Is Ceding Its Own AI Advantage" /&gt;&lt;hr&gt;
&lt;h1 id=&#34;forfeiting-the-frontier-how-washington-is-ceding-its-own-ai-advantage&#34;&gt;Forfeiting the Frontier: How Washington Is Ceding Its Own AI Advantage
&lt;/h1&gt;&lt;p&gt;On 12 June 2026, Commerce Secretary Howard Lutnick ordered Anthropic to suspend its two most capable models, Fable 5 and Mythos 5, for every foreign national. The ban covered foreign nationals abroad and inside the United States alike, including the company&amp;rsquo;s own non-citizen employees. No provider can sort a live user base by nationality in real time, so the practical effect was a worldwide shutoff of both models. Anthropic&amp;rsquo;s &lt;a class=&#34;link&#34; href=&#34;https://www.anthropic.com/news/fable-mythos-access&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;statement&lt;/a&gt; says the order cited &amp;ldquo;national security authorities&amp;rdquo; but gave no written detail, only a verbal account of a narrow technique.&lt;/p&gt;
&lt;p&gt;This episode will be litigated and probably resolved; Anthropic expects to restore access. But the important question is not whether one directive survives a court challenge. It is what a &lt;em&gt;pattern&lt;/em&gt; of maneuvers like this does to the very thing the United States probably wants to protect: its lead in frontier AI. These maneuvers erode that lead, and that they do so precisely &lt;em&gt;because&lt;/em&gt; of what they are: selective, improvised, and aimed at a domestic company rather than a foreign adversary.&lt;/p&gt;
&lt;h2 id=&#34;how-a-lead-actually-erodes&#34;&gt;How a lead actually erodes
&lt;/h2&gt;&lt;p&gt;A technological advantage is rarely lost the way people fear it will be, with a rival leaping ahead overnight. It erodes more slowly, from underneath. A frontier lead is not held by any single model or company. It is held by an &lt;em&gt;ecosystem&lt;/em&gt;: the researchers willing to build their careers in one country, the investors willing to fund decade-long bets there, and the market on which raw capability turns into products, standards, and dependencies that the rest of the world comes to rely on. Capability itself moves easily from place to place. Ecosystems stay put, right up until they don&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;What dislodges an ecosystem is not a single shock but a loss of confidence that the place is &lt;em&gt;predictable&lt;/em&gt;. Consider the people who sustain a frontier: a founder choosing where to incorporate, an investor pricing a fifteen-year position, a researcher deciding where to spend a career, a finance ministry weighing whether to build national systems on top of an American model. Each of these is a long-term bet. And each depends less on any single government action than on how erratic the government&amp;rsquo;s behaviour is overall. A country can absorb a great deal of policy that is heavy-handed but predictable and still remain the obvious place to build. What it cannot absorb is the impression that a model serving hundreds of millions of people on a Tuesday can be switched off by letter on a Friday, on contested grounds, against one company. That impression is what dissolves the ecosystem.&lt;/p&gt;
&lt;h2 id=&#34;these-are-maneuvers-not-policy&#34;&gt;These are maneuvers, not policy
&lt;/h2&gt;&lt;p&gt;It&amp;rsquo;s true that Mythos is no ordinary chatbot. Anthropic itself &lt;a class=&#34;link&#34; href=&#34;https://www.cbsnews.com/news/mythos-anthropic-ai-cybersecurity-risks-powell-bessent/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;describes it&lt;/a&gt; as having found previously unknown security flaws across major operating systems and browsers. That is a real capability, and it genuinely alarmed regulators.&lt;/p&gt;
&lt;p&gt;But the order fits neither the scope nor the logic of a genuine security measure. The model most users lost was Fable 5, the public and heavily safeguarded one. The stated reason was a &amp;ldquo;jailbreak&amp;rdquo; that, by Anthropic&amp;rsquo;s account, exposed only minor flaws that were already known, the kind of flaws that other public models, &lt;a class=&#34;link&#34; href=&#34;https://www.anthropic.com/news/fable-mythos-access&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI&amp;rsquo;s GPT-5.5 among them&lt;/a&gt;, reveal even without any such jailbreak. A genuine security measure applies to a whole class of products. This one named a single company while its closest competitor kept operating without restriction.&lt;/p&gt;
&lt;p&gt;That selectivity is not an accident; it is the pattern. The dispute goes back to February, when Anthropic refused to let the Pentagon use its models for autonomous weapons or domestic surveillance. The President then &lt;a class=&#34;link&#34; href=&#34;https://www.npr.org/2026/02/27/nx-s1-5729118/trump-anthropic-pentagon-openai-ai-weapons-ban&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ordered every agency to drop the company&lt;/a&gt;, and the Pentagon branded it a &amp;ldquo;supply-chain risk,&amp;rdquo; a label normally reserved for foreign adversaries. OpenAI secured a Defense Department deal within hours. A federal judge &lt;a class=&#34;link&#34; href=&#34;https://www.npr.org/2026/03/26/nx-s1-5762971/judge-temporarily-blocks-anthropic-ban&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;later blocked those moves&lt;/a&gt;, finding that they &amp;ldquo;appear designed to punish Anthropic&amp;rdquo; and amounted to &amp;ldquo;classic First Amendment retaliation.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The clearest sign is what the same government does with the same capability when it serves its own ends. The administration is reportedly &lt;a class=&#34;link&#34; href=&#34;https://techcrunch.com/2026/06/05/nsa-said-to-be-readying-anthropics-mythos-for-use-in-cyber-operations/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;running Mythos at the NSA&lt;/a&gt;, with Anthropic engineers embedded to support it, and the Pentagon&amp;rsquo;s own technology chief has &lt;a class=&#34;link&#34; href=&#34;https://www.cnbc.com/2026/05/01/pentagon-anthropic-blacklist-mythos-michael.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;called Mythos a &amp;ldquo;separate national security moment&amp;rdquo;&lt;/a&gt; that the government must harness, even as the supply-chain label remains in place. A capability cannot be too dangerous to show a foreign national in a coffee shop and, at the same time, important enough to run in the nation&amp;rsquo;s own cyber operations. In fairness, the order &lt;a class=&#34;link&#34; href=&#34;https://www.axios.com/2026/06/12/anthropic-trump-mythos-fable-national-security&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;followed&lt;/a&gt; an ignored request to delay the launch, so the government did have concerns and a channel for raising them.&lt;/p&gt;
&lt;p&gt;However, this kind of incoherence is exactly what long-term decisions weigh most heavily. A strict but consistent set of rules is a known cost, one the ecosystem can plan around. A government that bars a domestic company from offering the very capability the government itself runs, and that a rival sells freely, does not impose a known cost. It introduces unpredictability, and unpredictability is what makes a place the wrong one to build in.&lt;/p&gt;
&lt;h2 id=&#34;both-exits-cost-the-united-states&#34;&gt;Both exits cost the United States
&lt;/h2&gt;&lt;p&gt;If Anthropic stays put, it operates at the discretion of an administration willing to use its procurement and export powers against a vendor over a contract dispute. That is a precarious position for a company &lt;a class=&#34;link&#34; href=&#34;https://techcrunch.com/2026/05/28/anthropic-raises-65-billion-nears-1t-valuation-ahead-of-ipo/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;preparing a U.S. listing&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://thenextweb.com/news/apollo-blackstone-36bn-anthropic-chip-debt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;financing tens of billions of dollars in computing power&lt;/a&gt;. But capability does not stay locked inside one company&amp;rsquo;s distribution. If it cannot be deployed at scale from within the United States, the frontier simply advances somewhere with fewer constraints. The rational response for any government watching is what is often called &amp;ldquo;sovereign AI&amp;rdquo;: the principle that a nation should not build its critical systems on top of technology that a foreign executive can switch off overnight. Every maneuver of this kind strengthens that argument, and funds the non-American alternatives that follow from it.&lt;/p&gt;
&lt;p&gt;If Anthropic instead reduced its dependence on the United States, the disruption would be larger still. It would lose the U.S. market the moment a security pretext was invoked. More importantly, the American companies it connects to, the major cloud providers and enterprise channels, would be barred from dealing with a banned foreign entity, and that is a far larger commercial loss than any single contract. The honest counterpoint is that Anthropic&amp;rsquo;s reliance on U.S. capital and U.S. chips makes a clean exit more theory than plan. But that is exactly the point. A national champion that cannot easily leave is not a reassurance. It is a live demonstration, for everyone still deciding where to build, of how costly it is to be trapped.&lt;/p&gt;
&lt;h2 id=&#34;what-gets-priced-in&#34;&gt;What gets priced in
&lt;/h2&gt;&lt;p&gt;The narrow cost here is the disruption to Anthropic&amp;rsquo;s customers, which the company says it is working to reverse. The deeper cost falls on the one factor that actually decides who leads a decade from now: the willingness of talent, capital, and allied governments to commit, irreversibly, to the American frontier. That willingness depends on predictability, and predictability is exactly what a series of selective, improvised interventions destroys. &lt;a class=&#34;link&#34; href=&#34;https://fortune.com/2026/06/13/anthropic-disables-fable-mythos-export-controls-national-security-threat/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Veteran critics have warned&lt;/a&gt; of precisely this, about this very action: they expect it to push foreign-born researchers back to their home countries and to make American AI look, to investors, like an unsafe bet. The stated goal of the entire posture is to stay ahead of China. Undermining a domestic frontier lab, while a competitor and the government itself use the same capability, is the surest way to hand that lead away.&lt;/p&gt;
&lt;p&gt;Export controls are a tool for denying a capability to an adversary. Aimed instead at a domestic champion, over a capability the same government is running and a rival is selling without restriction, the tool points the wrong way. The capability does not disappear. It moves elsewhere, and the advantage (that was never the capability itself but the conditions that attract it) moves along with it.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Cloud Lock-in is Mostly Self-Inflicted</title>
        <link>https://colan.pro/blog/cloud-lock-in-is-mostly-self-inflicted/</link>
        <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/cloud-lock-in-is-mostly-self-inflicted/</guid>
        <description>&lt;img src="https://colan.pro/blog/cloud-lock-in-is-mostly-self-inflicted/cloud-lock-in-is-mostly-self-inflicted.png" alt="Featured image of post Cloud Lock-in is Mostly Self-Inflicted" /&gt;&lt;p&gt;Cloud lock-in feels like something the market does to you. Mostly, it&amp;rsquo;s a series of small architecture defaults you accepted without weighing the trade-offs.&lt;/p&gt;
&lt;p&gt;Two of them do most of the damage: too much cloud-specific infrastructure as code (IaC), and too many cloud-specific managed services. The providers steer you there by default, the tutorials assume it, and the path of least resistance quietly becomes the path of permanent residence.&lt;/p&gt;
&lt;p&gt;Both are choices. Both are fixable, provided you decide they matter early, while fixing them is still cheap.&lt;/p&gt;
&lt;h2 id=&#34;problem-1-cloud-specific-iac&#34;&gt;Problem 1: Cloud-specific IaC
&lt;/h2&gt;&lt;p&gt;Every cloud ships its own native IaC and its own native CI/CD, and each one is genuinely pleasant to use right up until the day you want to leave: CloudFormation, ARM/Bicep, Deployment Manager, plus the pipeline layer of GitHub Actions wired to one cloud&amp;rsquo;s identity model, Azure Pipelines tasks, and CodePipeline/CodeBuild.&lt;/p&gt;
&lt;p&gt;The pipeline layer is where this gets worse, because pipeline code is sneaky. People think of it as glue rather than infrastructure, so it doesn&amp;rsquo;t get the same scrutiny, and it metastasizes. My last client had approximately 80% of their automation living in Azure Pipelines: not just deployment steps, but environment logic, secret handling, approval gates, the works. None of that is portable. The day they want a second cloud, or a credible negotiating position with their first one, that 80% is a rewrite, not a migration. That&amp;rsquo;s nuts, and it&amp;rsquo;s also completely normal, which is the problem.&lt;/p&gt;
&lt;p&gt;The fix is boring and it works: write as much of your IaC as possible in &lt;strong&gt;Terraform&lt;/strong&gt; (or OpenTofu) and &lt;strong&gt;Ansible&lt;/strong&gt;, and treat anything cloud-specific as a liability you have to justify rather than a default you reach for.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Terraform owns the infrastructure: networks, compute, IAM, storage, the lot. One language, one state model, one mental model across every provider.&lt;/li&gt;
&lt;li&gt;Ansible owns configuration and the imperative bits Terraform is bad at.&lt;/li&gt;
&lt;li&gt;CI/CD becomes a thin orchestration layer whose only job is to &lt;em&gt;call&lt;/em&gt; Terraform and Ansible. The actual logic lives in version-controlled scripts and modules, not in proprietary pipeline YAML. If your pipeline definition is more than a few steps long, you&amp;rsquo;re putting business logic in the one place you can&amp;rsquo;t take with you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now the honest caveat, because anyone who&amp;rsquo;s actually done this will call me on it otherwise: Terraform is not a magic portability button. The HCL, the workflow, the state management, the module patterns, your team&amp;rsquo;s muscle memory all transfer. But a Terraform &lt;code&gt;aws_*&lt;/code&gt; resource is still an AWS resource. The &lt;em&gt;provider&lt;/em&gt; blocks are cloud-specific by definition, and you don&amp;rsquo;t get to write &lt;code&gt;resource &amp;quot;generic_database&amp;quot;&lt;/code&gt; and have it land on three clouds. What you get is a single tool and a single workflow wrapping every provider, so a migration becomes &amp;ldquo;rewrite the resource definitions&amp;rdquo; instead of &amp;ldquo;rewrite the resource definitions &lt;em&gt;and&lt;/em&gt; relearn the entire tooling stack &lt;em&gt;and&lt;/em&gt; port all the pipeline logic.&amp;rdquo; That&amp;rsquo;s a dramatically smaller blast radius, and it&amp;rsquo;s the difference between a switch you can credibly threaten and one you can&amp;rsquo;t.&lt;/p&gt;
&lt;h2 id=&#34;problem-2-cloud-specific-managed-services&#34;&gt;Problem 2: Cloud-specific managed services
&lt;/h2&gt;&lt;p&gt;This is the deeper hook, and it&amp;rsquo;s deeper precisely because the services are &lt;em&gt;good&lt;/em&gt;. Aurora, DynamoDB, Cosmos DB, BigQuery, SQS, the whole managed-everything catalog: these are genuinely excellent, and they remove real operational pain. That&amp;rsquo;s exactly what makes them the stickiest form of lock-in. You don&amp;rsquo;t notice the dependency forming, because every individual decision to use one was the sensible one.&lt;/p&gt;
&lt;p&gt;The portable alternative is to run open-source services yourself and let your IaC manage them: PostgreSQL instead of a proprietary managed database, an open message broker instead of the cloud-native queue. Package it as &lt;strong&gt;Helm&lt;/strong&gt; charts, manage those charts with Terraform, and the entire definition of your stateful services becomes provider-agnostic. Kubernetes ends up as the portability substrate: the cluster looks roughly the same whether the nodes underneath it are EC2, Azure VMs, or GCE, so the workload definitions ride along to wherever you point them.&lt;/p&gt;
&lt;p&gt;And here&amp;rsquo;s where I have to argue against my own enthusiasm, because &amp;ldquo;just self-host Postgres on Kubernetes&amp;rdquo; is the kind of advice that sounds clean on social media and bites you at 3 a.m.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Managed services exist for a reason.&lt;/strong&gt; When you self-host PostgreSQL, &lt;em&gt;you&lt;/em&gt; now own backups, failover, point-in-time recovery, version upgrades, patching, and the pager. The cloud was charging you for that, and a lot of teams genuinely come out ahead paying the premium rather than staffing the expertise. Portability is a benefit with a recurring operational cost attached, and you should price both sides before deciding.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kubernetes is overkill for plenty of projects.&lt;/strong&gt; If you&amp;rsquo;re running a handful of services, standing up a cluster to win portability you&amp;rsquo;ll never exercise is a bad trade. The Terraform code stays portable either way, which is the real point, so you can get a lot of the benefit without committing to K8s as your runtime for everything.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stateful workloads on Kubernetes are their own discipline.&lt;/strong&gt; Operators have made this far more reasonable than it was five years ago, but a database on K8s is not a fire-and-forget proposition. Go in with eyes open.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So this isn&amp;rsquo;t &amp;ldquo;never touch a managed service.&amp;rdquo; It&amp;rsquo;s &amp;ldquo;decide deliberately.&amp;rdquo; Use a proprietary managed service when the operational savings clearly beat the lock-in cost; just know that you&amp;rsquo;re making that trade, in writing, rather than discovering it the day you try to leave.&lt;/p&gt;
&lt;h2 id=&#34;how-to-actually-decide&#34;&gt;How to actually decide
&lt;/h2&gt;&lt;p&gt;The useful question isn&amp;rsquo;t &amp;ldquo;cloud-specific or portable?&amp;rdquo; in the abstract. It&amp;rsquo;s: &lt;em&gt;for this specific component, what does the exit cost, and is the convenience worth that price?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A rough hierarchy that&amp;rsquo;s served me well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Default to portable for the foundation:&lt;/strong&gt; IaC tooling, CI/CD logic, networking and identity patterns, your stateful core. This is the stuff that&amp;rsquo;s expensive to unwind later and cheap to get right now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Allow cloud-specific where the value is genuinely differentiated&lt;/strong&gt; and the alternative would be a heroic amount of undifferentiated heavy lifting. Some managed services really are better than anything you&amp;rsquo;d run yourself, and dogma here just costs you money.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refuse to let pipeline code become load-bearing.&lt;/strong&gt; This is the cheapest win on the list and the one people skip. Keep the proprietary layer thin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The strategic reason this is worth the discipline ties straight back to the competition story. When &lt;a class=&#34;link&#34; href=&#34;https://www.cbc.ca/news/business/cloud-computing-competition-9.7219996&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a recent report&lt;/a&gt; called Canada&amp;rsquo;s cloud market &amp;ldquo;broken&amp;rdquo;, its sharpest recommendation wasn&amp;rsquo;t about breaking up the incumbents; it was about forcing compatibility so customers can actually switch. Regulators are circling egress fees and data portability for the same reason: lock-in gives hyperscalers pricing power over customers who can&amp;rsquo;t credibly leave. But you don&amp;rsquo;t have to wait for a regulator to hand you leverage. An architecture that &lt;em&gt;could&lt;/em&gt; move is a negotiating position whether or not you ever pull the trigger, and most of the time you won&amp;rsquo;t need to, because the provider knows you could. The cheapest exit is the one you designed in from day one. The most expensive one is the rewrite you start the morning you finally decide you&amp;rsquo;ve had enough.&lt;/p&gt;
&lt;p&gt;The goal was never to leave. It&amp;rsquo;s to stay because you decided to, not because you had no other option. That choice gets made early, in the boring decisions, or it doesn&amp;rsquo;t get made at all.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Announcing Drubernetes v2: Moving from Bitnami to the Official MariaDB Operator</title>
        <link>https://colan.pro/blog/drubernetes-v2-bitnami-to-official-mariadb-operator/</link>
        <pubDate>Wed, 22 Oct 2025 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drubernetes-v2-bitnami-to-official-mariadb-operator/</guid>
        <description>&lt;img src="https://colan.pro/blog/drubernetes-v2-bitnami-to-official-mariadb-operator/drubernetes-v2-bitnami-to-official-mariadb-operator.png" alt="Featured image of post Announcing Drubernetes v2: Moving from Bitnami to the Official MariaDB Operator" /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;This article was &lt;a class=&#34;link&#34; href=&#34;https://backupscale.com/posts/drubernetes-v2-bitnami-to-official-mariadb-operator/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;originally published on the BackUpScale blog&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;why-it-matters&#34;&gt;Why It Matters
&lt;/h2&gt;&lt;p&gt;For many open-source projects and small teams, Bitnami’s charts were the default starting point for running DBs and applications on Kubernetes. When a large vendor changes course, it sends ripples across the ecosystem; it can suddenly make basic infrastructure harder or more expensive to maintain. Drubernetes v2 ensures that Drupal deployments remain fully open, self-contained, and future-proof, regardless of corporate licensing shifts. Community-driven alternatives are essential to preserve innovation and accessibility.&lt;/p&gt;
&lt;h2 id=&#34;background-why-drubernetes-needed-a-v2&#34;&gt;Background: Why Drubernetes Needed a v2
&lt;/h2&gt;&lt;p&gt;When we first built Drubernetes, the goal was simple: make it easy for various organizations to deploy Drupal on Kubernetes using Terraform for infrastructure automation. Our stack relied heavily on community-maintained Helm charts (most notably &lt;a class=&#34;link&#34; href=&#34;https://artifacthub.io/packages/helm/bitnami/mariadb&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bitnami’s MariaDB chart&lt;/a&gt;) for reliability and ease of integration.&lt;/p&gt;
&lt;p&gt;But the open-source ecosystem around Bitnami has shifted dramatically.&lt;/p&gt;
&lt;h2 id=&#34;bitnamis-policy-shift-from-open-access-to-paywall&#34;&gt;Bitnami’s Policy Shift: From Open Access to Paywall
&lt;/h2&gt;&lt;p&gt;Bitnami historically maintained one of the best collections of open Helm charts in the cloud-native space. These charts were widely used for MySQL, MariaDB, Redis, WordPress, and many others, often forming the foundation of production workloads for startups and open-source projects.&lt;/p&gt;
&lt;p&gt;However, following VMware’s 2022 acquisition by Broadcom and its ensuing restructuring, &lt;strong&gt;Bitnami’s open chart repositories were deprecated&lt;/strong&gt;, and &lt;strong&gt;support for their community versions effectively ended&lt;/strong&gt;. As covered in &lt;a class=&#34;link&#34; href=&#34;https://fastcode.io/2025/08/30/the-69-billion-domino-effect-how-vmwares-debt-fueled-acquisition-is-killing-open-source-one-repository-at-a-time/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Fastcode’s analysis&lt;/a&gt;, Broadcom’s pivot toward expensive subscription-only licensing has created a domino effect, shuttering long-standing open-source pipelines and forcing projects like ours to re-architect.&lt;/p&gt;
&lt;p&gt;For open-source maintainers like &lt;a class=&#34;link&#34; href=&#34;https://backupscale.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;BackUpScale&lt;/a&gt;, continuing to use Bitnami’s images now involves licensing uncertainty,
limited updates, instability and the risk of losing upstream security fixes.&lt;/p&gt;
&lt;p&gt;Simply put: &lt;strong&gt;Bitnami’s stack is no longer a viable base for sustainable open-source projects with limited funding.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-changed-in-drubernetes-v2&#34;&gt;What Changed in Drubernetes v2
&lt;/h2&gt;&lt;p&gt;To keep Drubernetes fully open and future-proof, we replaced our only Bitnami dependency, MariaDB, with the official &lt;a class=&#34;link&#34; href=&#34;https://mariadb.com/docs/tools/mariadb-enterprise-operator/installation/helm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MariaDB Enterprise Operator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can review the full changelog on the &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/backupscale/drubernetes/-/releases/2.0.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;2.0.0 release page&lt;/a&gt; and discussion in &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/backupscale/drubernetes/-/issues/3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Issue #3&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;migration-guide-upgrading-from-v1x-to-v20&#34;&gt;Migration Guide: Upgrading from v1.x to v2.0
&lt;/h2&gt;&lt;p&gt;While this release represents a major step forward, the migration process does require manual intervention due to the difference in architectures.&lt;/p&gt;
&lt;p&gt;Please review the complete details in the &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/backupscale/drubernetes/-/releases/2.0.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;looking-ahead&#34;&gt;Looking Ahead
&lt;/h2&gt;&lt;p&gt;Drubernetes v2 isn’t just about keeping up with upstream changes.  It’s about reinforcing the open-source foundations we depend on. By moving to the official Helm charts, we gain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transparent governance and roadmaps&lt;/li&gt;
&lt;li&gt;Consistent upstream support&lt;/li&gt;
&lt;li&gt;Easier compliance for enterprise users&lt;/li&gt;
&lt;li&gt;Freedom from vendor lock-in&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We’ll continue to monitor the health of the operator ecosystem and ensure Drubernetes remains reliable, free from opaque licensing traps.&lt;/p&gt;
&lt;p&gt;For more information, visit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The introducing article:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://backupscale.com/posts/drubernetes-terraform-module-for-kubernetes-clusters/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Want to Run Drupal in Kubernetes? Try Our New Terraform Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The project page:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/backupscale/drubernetes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gitlab.com/backupscale/drubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Terraform registry module:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/modules/BackUpScale/drupal/kubernetes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;BackUpScale/drupal/kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Comparing Canada’s Challenger Banks for Business: Loop, Venn, EQ Bank &amp; Wealthsimple</title>
        <link>https://colan.pro/blog/comparing-canadian-challenger-banks-for-business/</link>
        <pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/comparing-canadian-challenger-banks-for-business/</guid>
        <description>&lt;img src="https://colan.pro/blog/comparing-canadian-challenger-banks-for-business/comparing-canadian-challenger-banks-for-business.png" alt="Featured image of post Comparing Canada’s Challenger Banks for Business: Loop, Venn, EQ Bank &amp; Wealthsimple" /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update 2026-06-28:&lt;/strong&gt; When I originally published this, Wealthsimple didn&amp;rsquo;t support business accounts, but they started to on March 19th, 2026, and then introduced a payment card on June 18th.  So I thought it was time to include them in the comparison table.  Check it out below!&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Small business owners and startup founders across Canada are exploring modern fintech banking alternatives to escape the frustrations of the Big 5 banks (BMO, Scotiabank, CIBC, RBC, and TD). New challenger banks like &lt;strong&gt;Loop&lt;/strong&gt;, &lt;strong&gt;Venn&lt;/strong&gt; (formerly known as Vault), and &lt;strong&gt;EQ Bank&lt;/strong&gt; are offering digital-first business accounts with low fees and innovative features. In this article, we’ll compare the key differences between these three fintech banking options for Canadian businesses. We’ll also touch on why some other names (like Wealthsimple or Tangerine) aren’t included, and mention how an international option (Wise) fits into the picture.&lt;/p&gt;
&lt;h2 id=&#34;why-not-include-wealthsimple-or-tangerine&#34;&gt;Why Not Include Wealthsimple or Tangerine?
&lt;/h2&gt;&lt;p&gt;Two other popular financial brands often come up in conversations about fintech banking: &lt;strong&gt;Wealthsimple&lt;/strong&gt; and &lt;strong&gt;Tangerine&lt;/strong&gt;. However, neither currently provides a full-fledged business &lt;strong&gt;operating account&lt;/strong&gt; for day-to-day transactions, so we haven’t included them in the main comparison:&lt;/p&gt;
&lt;h3 id=&#34;wealthsimple&#34;&gt;Wealthsimple
&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Wealthsimple for Business&lt;/em&gt; is essentially a high-interest savings and investment account for corporations, not a business chequing/operating account. In fact, Wealthsimple explicitly states, &lt;em&gt;“We don’t offer business banking at the moment”&lt;/em&gt;. Their “Save for Business” account is only for parking surplus cash (it even requires you to have a separate business chequing account elsewhere to use it) and is limited to incorporated businesses (not available for sole proprietors). In short, Wealthsimple can help your company invest or earn interest on idle funds, but you &lt;strong&gt;cannot run daily business payments&lt;/strong&gt; through it.&lt;/p&gt;
&lt;h3 id=&#34;tangerine&#34;&gt;Tangerine
&lt;/h3&gt;&lt;p&gt;Tangerine (the online bank backed by Scotiabank, previously ING Direct) &lt;strong&gt;only offers business savings accounts and GICs&lt;/strong&gt;, not a transactional chequing account. The Tangerine Business Savings Account is designed to &lt;em&gt;complement&lt;/em&gt; a business chequing at another institution, meaning &lt;strong&gt;you must already have a business account elsewhere&lt;/strong&gt; to use it. It’s great for earning high interest on business cash, but you can’t write cheques, deposit client payments, or pay bills directly from a Tangerine business account. Tangerine’s focus is strictly on savings products for businesses, so it’s outside the scope of comparing operating accounts.&lt;/p&gt;
&lt;p&gt;Now, let’s turn our attention to three fintech players that &lt;em&gt;do&lt;/em&gt; offer operating business accounts: &lt;strong&gt;Loop&lt;/strong&gt;, &lt;strong&gt;Venn&lt;/strong&gt;, and &lt;strong&gt;EQ Bank&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;challenger-bank-comparison-overview&#34;&gt;Challenger Bank Comparison Overview
&lt;/h2&gt;&lt;p&gt;Below is a side-by-side comparison of features for Loop, Venn, and EQ Bank business accounts. We’ll dive into many of these features in the commentary that follows.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Feature&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Loop&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Venn&lt;/strong&gt; (formerly Vault)&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;EQ Bank&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Wealthsimple&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Business types supported&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://app.bankonloop.com/register&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Not sole proprietorships&lt;/a&gt; (corporations only)&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.venn.ca/en/articles/10503550-who-can-sign-up-for-an-account&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Corporations only&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.eqbank.ca/business/business-banking/business-account&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Sole proprietors &amp;amp; corporations&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/business/chequing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Incorporated businesses only&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;CDIC-insured accounts&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Planned (via partner bank)&lt;/td&gt;
          &lt;td&gt;Yes (via partner bank)&lt;/td&gt;
          &lt;td&gt;Sole proprietorships only&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/business/chequing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Yes&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Additional accounts&lt;/strong&gt; (multiple accounts or sub-accounts under one business)&lt;/td&gt;
          &lt;td&gt;No (one account per currency)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.venn.ca/pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;5 in free plan&lt;/a&gt; (sub-accounts)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.eqbank.ca/business/business-banking/business-account&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Up to 10 in total&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/business/chequing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Up to 8&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Non-“prepaid” payment cards&lt;/strong&gt; (corporate debit/credit card availability)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Visa debit/credit card&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Mastercard debit/credit card&lt;/td&gt;
          &lt;td&gt;No, &lt;a class=&#34;link&#34; href=&#34;https://www.eqbank.ca/business/card&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;prepaid MastCard only&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;No, &lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/business/chequing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;prepaid Visa only&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Add funds via Interac e-Transfer&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Planned (not yet supported)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Via &lt;a class=&#34;link&#34; href=&#34;https://help.venn.ca/en/articles/9236355-how-long-does-it-take-to-send-or-receive-or-add-money-via-interac&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;sending e-Transfer to yourself&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Supports incoming e-Transfers&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; after setting up autodeposit&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Get paid via Interac e-Transfer&lt;/strong&gt; (receive from others)&lt;/td&gt;
          &lt;td&gt;Planned (not yet)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://help.venn.ca/en/articles/9236355-how-long-does-it-take-to-send-or-receive-or-add-money-via-interac&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Supports incoming e-Transfers&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Supports incoming e-Transfers&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; after setting up autodeposit&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Send Interac payments&lt;/strong&gt; (send e-Transfers out)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No&lt;/strong&gt; (use EFT/wire instead)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.venn.ca/resources/new-feature-launch-send-payments-via-interac-straight-through-vault&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Can send Interac e-Transfers&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Can send Interac e-Transfers&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/business/chequing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Can send Interac e-Transfers&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Helpful chatbot&lt;/strong&gt; (in-app support chat)&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Proof of account ownership&lt;/strong&gt; (signed/stamped document)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Provides official letter&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Provides official letter&lt;/td&gt;
          &lt;td&gt;Possibly on request, void cheque only by default&lt;/td&gt;
          &lt;td&gt;Possibly on request, void cheque only by default&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Secure 2FA login&lt;/strong&gt; (TOTP, passkeys support)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Supports authenticator app&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Supports authenticator app&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No:&lt;/strong&gt; Only basic 2FA (email/SMS)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Passkeys and authenticator apps&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Full-year statements&lt;/strong&gt; (annual statement or summary)&lt;/td&gt;
          &lt;td&gt;No (monthly statements only)&lt;/td&gt;
          &lt;td&gt;No (monthly statements only)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Print 12 months on Transactions page&lt;/td&gt;
          &lt;td&gt;No (monthly statements only)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Free transactions on free plan&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Unlimited free transactions&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No:&lt;/strong&gt; Pay per transaction on free tier&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Most free (limits on free Interac)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Unlimited free transactions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Cashback on card spending&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;0% (point-based rewards only)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;1%&lt;/strong&gt; cashback on all spend&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.eqbank.ca/business/card&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;1% cash back with $10k monthly spend&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.wealthsimple.com/hc/en-ca/articles/51293708721179-Request-a-prepaid-business-Visa-card&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;1%&lt;/strong&gt; cashback on all spend&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Automated recurring payments&lt;/strong&gt; (scheduled payments)&lt;/td&gt;
          &lt;td&gt;Planned (not yet)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Can schedule recurring payments&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Can schedule recurring payments&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; With Interac e-Transfers &amp;amp; bill payments&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Automatic balance top-ups&lt;/strong&gt; (auto-transfer to maintain balance)&lt;/td&gt;
          &lt;td&gt;Planned (not yet)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Auto top-ups supported&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;, but when deposits come in, &lt;a class=&#34;link&#34; href=&#34;https://help.wealthsimple.com/hc/en-ca/articles/49708719281051-Set-up-Auto-save-for-your-Business-chequing-account&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a percentage can be auto-saved elsewhere&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Pay bills through account&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Can pay billers through the Canadian bill payment system&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Can pay billers through the Canadian bill payment system&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Pay business taxes through account&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Can pay Canada Revenue Agency (CRA) / business taxes&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/business/chequing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Can pay Canada Revenue Agency (CRA) / business taxes&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Secure document upload&lt;/strong&gt; (for onboarding or support)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Upload documents in portal&lt;/td&gt;
          &lt;td&gt;No (use email for documents)&lt;/td&gt;
          &lt;td&gt;No (use email for documents)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Upload documents in portal&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Mobile wallet support&lt;/strong&gt; (Apple/Google/Samsung)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://help.bankonloop.com/s/article/How-to-Add-Your-Loop-Card-to-Apple-Pay-or-Google-Pay&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apple Pay &amp;amp; Google Pay only&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.venn.ca/en/articles/12141883-how-do-i-add-my-venn-mastercard-for-google-pay&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Pay&lt;/a&gt; only, so far&lt;/td&gt;
          &lt;td&gt;N/A (no card)&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.wealthsimple.com/hc/en-ca/articles/4854728778395-Adding-your-virtual-Visa-or-Mastercard-to-a-digital-wallet&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apply &amp;amp; Google, but not Samsung&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Foreign currency accounts&lt;/strong&gt; (operating accounts in other currencies)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; USD, EUR, GBP accounts&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; USD, EUR, GBP accounts&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;None&lt;/strong&gt; (CAD only)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;, but USD accounts are planned&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Foreign exchange (FX) conversion fee&lt;/strong&gt; (currency conversion markup)&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bankonloop.com/pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;0.50%&lt;/strong&gt; (Free plan), &lt;strong&gt;0.25%&lt;/strong&gt; (Plus@$49/mo), &lt;strong&gt;0.10%&lt;/strong&gt; (Power@$199/mo)&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.venn.ca/pricing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;0.45%&lt;/strong&gt; (Essentials@$0/mo), &lt;strong&gt;0.35%&lt;/strong&gt; (Plus@$40/mo), &lt;strong&gt;0.25%&lt;/strong&gt; (Pro@$100/mo)&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;N/A&lt;/strong&gt; (no FX service for business; only on personal side)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;N/A&lt;/strong&gt; until USD accounts are available&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Team access (multi-user support)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; Included on free plan (invite team/users)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Limited:&lt;/strong&gt; Paid plan required to add non-owner users&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;None:&lt;/strong&gt; No multi-user login support&lt;/td&gt;
          &lt;td&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.wealthsimple.com/hc/en-ca/articles/50368260310811-Add-co-owners-to-your-Business-account&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Co-owners only&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Referral program&lt;/strong&gt; (rewards for referrals)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.bankonloop.com/refer&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Offers referral bonuses&lt;/a&gt; &lt;em&gt;(&lt;a class=&#34;link&#34; href=&#34;https://app.bankonloop.com/register?Invitation-Code=LOOP811SISJ&amp;amp;campaign=In-App%20Referral&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Author’s Loop referral code&lt;/a&gt;)&lt;/em&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.venn.ca/legal/referral-program-agreement-2025&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Offers referral bonuses, both parties&lt;/a&gt; &lt;em&gt;(&lt;a class=&#34;link&#34; href=&#34;https://app.venn.ca/signup?referral=qttcajnd&amp;amp;utm_source=app&amp;amp;utm_campaign=referral&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Author’s Venn referral link&lt;/a&gt;)&lt;/em&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;No&lt;/strong&gt; (business accounts have no referral program)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Yes:&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.wealthsimple.com/en-ca/referrals&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Offers referral bonuses, both parties&lt;/a&gt; &lt;em&gt;(&lt;a class=&#34;link&#34; href=&#34;https://wealthsimple.com/invite/1OQZCQ&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Author’s Wealthsimple referral link&lt;/a&gt;)&lt;/em&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Table: Feature comparison of Loop vs. Venn vs. EQ Bank vs. Wealthsimple business accounts.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Below we discuss many of these items in detail.&lt;/p&gt;
&lt;h2 id=&#34;business-account-eligibility-who-can-sign-up&#34;&gt;Business Account Eligibility (Who Can Sign Up)
&lt;/h2&gt;&lt;h3 id=&#34;busines-types&#34;&gt;Busines Types
&lt;/h3&gt;&lt;p&gt;One fundamental difference is &lt;strong&gt;which types of businesses each platform will accept.&lt;/strong&gt; Both &lt;strong&gt;Loop&lt;/strong&gt; and &lt;strong&gt;Venn&lt;/strong&gt; currently cater &lt;strong&gt;exclusively to registered corporations&lt;/strong&gt; (incorporated companies). Venn’s help center makes it clear that &lt;a class=&#34;link&#34; href=&#34;https://help.venn.ca/en/articles/10503550-who-can-sign-up-for-an-account&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;they only support corporations&lt;/a&gt;, and Loop’s onboarding is similarly geared toward corporations (and potentially other formal business entities), rather than simple sole proprietorships. In contrast, &lt;strong&gt;EQ Bank&lt;/strong&gt; is more inclusive; its business account is open to &lt;strong&gt;both corporations and sole proprietors&lt;/strong&gt; (as long as the sole proprietorship is a registered business under your own name).&lt;/p&gt;
&lt;h3 id=&#34;geography&#34;&gt;Geography
&lt;/h3&gt;&lt;p&gt;Notably, neither Venn nor EQ Bank’s business accounts are available to Quebec businesses at the time of writing. Venn explicitly does &lt;em&gt;not&lt;/em&gt; support businesses in Quebec yet, and EQ Bank’s sign-up page likewise notes Quebec is excluded for now. Loop is based in Toronto and does not list the same regional restriction so Quebec companies should be able to use Loop, which could be a deciding factor if you operate there.&lt;/p&gt;
&lt;h2 id=&#34;deposit-insurance&#34;&gt;Deposit Insurance
&lt;/h2&gt;&lt;p&gt;When it comes to the safety of your deposits, &lt;strong&gt;EQ Bank has the clear edge&lt;/strong&gt; by virtue of being a bank. EQ Bank is a trademark of Equitable Bank, which is a CDIC member institution. This means &lt;strong&gt;funds in an EQ Bank business account are eligible for CDIC deposit insurance&lt;/strong&gt;, up to $100,000 per depositor (in the “business accounts” category). However, there’s an important nuance: EQ clarifies that &lt;strong&gt;sole proprietorship&lt;/strong&gt; deposits are insured as part of your personal coverage (since a sole proprietorship isn’t a separate legal entity). Corporate accounts at EQ Bank may not receive separate CDIC coverage beyond that (corporate entities can be considered distinct depositors, but CDIC insurance for corporate deposits can depend on account structuring; EQ’s documentation emphasizes coverage for sole proprietors). In summary, &lt;strong&gt;EQ Bank offers the reassurance of CDIC insurance&lt;/strong&gt;, particularly for sole proprietors’ funds.&lt;/p&gt;
&lt;p&gt;Neither Loop nor Venn is a bank themselves, so &lt;strong&gt;deposits with Loop or Venn are not directly CDIC-insured&lt;/strong&gt; (if either company were to fail, the funds &lt;a class=&#34;link&#34; href=&#34;https://www.venn.ca/legal/terms-of-service#:~%5c:text=unsecured%20claim%20against%20Venn%20and,the%20specified%20bank%20account%20details&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;aren’t guaranteed by the government&lt;/a&gt;). That said, both use partner financial institutions to hold client funds. Loop has indicated that its Canadian dollar accounts are held with a &lt;strong&gt;CDIC member bank&lt;/strong&gt; (so effectively the funds &lt;strong&gt;are&lt;/strong&gt; insured via that partner). Venn likewise holds funds with “Tier 1” partner banks, and while they &lt;em&gt;offer&lt;/em&gt; CDIC-insured products like GICs through a partner, the &lt;strong&gt;operating balances&lt;/strong&gt; in Venn are not themselves CDIC-insured as of now (Venn’s terms describe your balance as an “unsecured claim” against Venn, not covered by deposit insurance). In the future, both Loop and Venn may obtain their own CDIC membership or otherwise make insurance more explicit (“Planned”), but currently &lt;strong&gt;only EQ Bank provides clear CDIC protection&lt;/strong&gt; for your business deposits.&lt;/p&gt;
&lt;h2 id=&#34;account-security&#34;&gt;Account Security
&lt;/h2&gt;&lt;p&gt;On security features, all three platforms use basic two-factor authentication (2FA) for logins, but &lt;strong&gt;Loop and Venn support more secure methods&lt;/strong&gt; via authenticator apps. EQ Bank’s 2FA for business accounts relies on sending a code via email, which is considered less secure than app-based 2FA. Loop and Venn, being newer platforms, allow users to set up TOTP (time-based one-time password) authenticator apps. This is a plus for those concerned about account security.  You might prefer Loop or Venn if you want the option to secure your login with something like &lt;a class=&#34;link&#34; href=&#34;https://proton.me/authenticator&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Proton Authenticator&lt;/a&gt; (or any other password manager / authenticator that suppports TOTP). Regardless, all three take security seriously (encryption, fraud monitoring, etc.), but the &lt;strong&gt;extra 2FA methods&lt;/strong&gt; on Loop and Venn give them a slight edge for the security-conscious.&lt;/p&gt;
&lt;h2 id=&#34;account-structure-single-vs-multiple-accounts&#34;&gt;Account Structure: Single vs Multiple Accounts
&lt;/h2&gt;&lt;p&gt;If your business likes to &lt;strong&gt;use multiple accounts&lt;/strong&gt; for budgeting or fund separation, note the differences in how each platform handles this.&lt;/p&gt;
&lt;h3 id=&#34;loop&#34;&gt;Loop
&lt;/h3&gt;&lt;p&gt;Loop provides one primary account in each supported currency (CAD by default, and USD/EUR/GBP if you activate global accounts). You &lt;strong&gt;cannot open additional “sub-accounts”&lt;/strong&gt; in the same currency for free at this time; essentially, Loop gives you one account per currency. For example, you might have a CAD account and also a USD account with Loop, but you can’t have two separate CAD accounts under the same business profile. This may change in the future (Loop has hinted at adding multiple sub-accounts), but currently it’s one account per currency on the platform.&lt;/p&gt;
&lt;h3 id=&#34;venn&#34;&gt;Venn
&lt;/h3&gt;&lt;p&gt;Venn allows multiple accounts through a &lt;strong&gt;“sub-accounts” feature&lt;/strong&gt;, which is great for organizing funds (e.g., setting aside money for taxes, payroll, etc. in separate buckets). On Venn’s free &lt;strong&gt;Essentials&lt;/strong&gt; plan, you can create up to &lt;strong&gt;5 sub-accounts&lt;/strong&gt;. If you upgrade to the paid &lt;strong&gt;Plus&lt;/strong&gt; or &lt;strong&gt;Pro&lt;/strong&gt; plans, that limit increases (10 sub-accounts on Plus, and unlimited on Pro). All these accounts can be in any of the supported currencies. This flexibility is a notable advantage of Venn for businesses that want &lt;em&gt;envelope budgeting&lt;/em&gt; or just separate ledgers for different purposes without opening entirely new bank accounts.&lt;/p&gt;
&lt;h3 id=&#34;eq-bank&#34;&gt;EQ Bank
&lt;/h3&gt;&lt;p&gt;EQ Bank also supports multiple accounts; you can open up to &lt;strong&gt;10 separate EQ Bank Business Accounts&lt;/strong&gt; for one business. Each account earns interest individually and can be named for its purpose. Since EQ doesn’t offer sub-account “buckets” within one login, those 10 are essentially 10 distinct bank accounts (but all under your business profile and accessible in one dashboard). That’s plenty for most small businesses’ needs. Keep in mind all those accounts will be CAD only (no foreign currency), but you could, for example, have an &lt;strong&gt;Operating Account&lt;/strong&gt;, a &lt;strong&gt;Savings Account&lt;/strong&gt;, and other specific accounts and transfer between them easily, all with no fees.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interest on balances&lt;/strong&gt; is another consideration here. EQ Bank stands out for offering a high interest rate (currently &lt;strong&gt;2.50%&lt;/strong&gt; interest on the full balance of its business accounts). This effectively turns every dollar in your EQ accounts into interest-earning savings until you need to spend it. Neither Loop nor Venn pay interest on ordinary balances (in fact, both explicitly state &lt;strong&gt;no interest on balance&lt;/strong&gt; as a trade-off). Venn’s workaround is that it offers GICs (Guaranteed Investment Certificates) within the platform if you want to park money for interest.  Those GIC funds &lt;em&gt;are&lt;/em&gt; CDIC-insured through Peoples Trust and currently yield around 5%, but they aren’t accessible for daily banking until maturity. Loop does not offer any interest-bearing products at the moment (Loop’s focus is more on saving you fees rather than paying interest). So, if maximizing interest on idle cash is a priority, &lt;strong&gt;EQ Bank’s 2.50% yield on everyday business balances is very attractive&lt;/strong&gt;, whereas Loop/Venn give 0% on deposits (you’d have to move money out to an investment to earn interest).&lt;/p&gt;
&lt;h2 id=&#34;payments-and-money-movement-interac-wires-deposits&#34;&gt;Payments and Money Movement (Interac, Wires, Deposits)
&lt;/h2&gt;&lt;p&gt;A critical aspect of any operating account is how you can &lt;strong&gt;move money in and out&lt;/strong&gt;. Here’s how our three contenders compare on payments and transfers.&lt;/p&gt;
&lt;h3 id=&#34;interac-e-transfers&#34;&gt;Interac e-Transfers
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;EQ Bank and Venn both fully support Interac e-Transfer for Canadian dollar payments&lt;/strong&gt;, while Loop currently does not (as of this writing). With &lt;strong&gt;EQ Bank&lt;/strong&gt;, you can send up to 50 e-Transfers per month for free (and 100 incoming e-Transfers for free). That’s usually plenty for a small business; if you exceed 50 outgoing e-Transfers in a month, fees would apply ($0.50 each beyond the free limit). &lt;strong&gt;Venn&lt;/strong&gt; allows sending and receiving Interac e-Transfers as well. On Venn’s free plan, outgoing Interac transfers are actually one of the few things that might incur a fee (Venn’s pricing mentions a $2 fee for local transfers on the free tier), but the speed and convenience are there. &lt;strong&gt;Loop&lt;/strong&gt;, on the other hand, does &lt;em&gt;not&lt;/em&gt; support sending Interac e-Transfers yet, and you can’t have clients send money to your Loop account via Interac either (Loop lacks an email or phone number for auto-deposit). In fact, a noted drawback is you &lt;strong&gt;“can’t receive CAD payments from customers”&lt;/strong&gt; via e-Transfer into Loop. Loop has this feature on the roadmap (marked as “Planned”), but for now, moving Canadian dollars to/from Loop requires linking an external bank (ACH/EFT) or using wire transfers. If your business uses a lot of e-Transfers with Canadian vendors or clients, this is a significant point in favor of Venn or EQ Bank.&lt;/p&gt;
&lt;h3 id=&#34;direct-deposits-and-efts&#34;&gt;Direct deposits and EFTs
&lt;/h3&gt;&lt;p&gt;All three platforms let you do traditional EFT or ACH transfers. &lt;strong&gt;Loop&lt;/strong&gt; and &lt;strong&gt;Venn&lt;/strong&gt; actually provide you with &lt;em&gt;real bank account numbers&lt;/em&gt; (Loop gives you a Canadian transit and account number for CAD, plus US ACH details for USD, etc.; Venn does similarly) so you can set up direct deposit or pre-authorized debits. &lt;strong&gt;EQ Bank&lt;/strong&gt; is a real bank account as well (transit/account under Equitable Bank). So you can, for example, have your payment processor deposit funds directly, or link PayPal/Stripe, etc., in all cases. Incoming and outgoing EFTs are &lt;strong&gt;free&lt;/strong&gt; for all three. Loop and Venn both emphasize &lt;em&gt;free&lt;/em&gt; domestic transfers (Loop even markets that it has unlimited free electronic payments, no fees). EQ Bank too charges no fees for EFT transfers. There may be timing differences (Loop and Venn might process EFTs as electronic debits that take 1-2 business days; EQ does overnight batch processing). Overall, &lt;strong&gt;routine bank transfers (EFT/ACH)&lt;/strong&gt; are a strength of all three; you aren’t nickel-and-dimed for electronic transfers as you would be at some big banks.&lt;/p&gt;
&lt;h3 id=&#34;wire-transfers-and-international-payments&#34;&gt;Wire transfers and international payments
&lt;/h3&gt;&lt;p&gt;This is where &lt;strong&gt;Loop and Venn truly shine&lt;/strong&gt; compared to both EQ and traditional banks. &lt;strong&gt;Loop&lt;/strong&gt; allows you to send wire payments globally &lt;em&gt;for free&lt;/em&gt; (no wire fees at all); you only pay the currency conversion fee if it involves FX. Loop supports sending to 180+ countries in 37 currencies, and even lets you send money &lt;strong&gt;to yourself&lt;/strong&gt; in another bank account abroad for free. &lt;strong&gt;Venn&lt;/strong&gt; also supports a wide range of international transfers (200+ countries). On the free plan Venn does charge a $10 fee to send an international wire, which is still far cheaper than a typical bank ($30–$50), but not zero. On Venn’s paid plans, the international wire fee drops ($8 on Plus, $6 on Pro). Receiving international wires in Venn is free. &lt;strong&gt;EQ Bank&lt;/strong&gt;, unfortunately, does not currently support sending international wires or foreign currency transfers from the business account at all; you can only send/receive Canadian payments (EFT, Interac) in EQ’s business offering. So if you need to pay overseas suppliers or receive USD/EUR wires regularly, EQ Bank alone won’t suffice (you’d need a separate solution, possibly why you’d consider Loop or Venn in the first place).&lt;/p&gt;
&lt;h3 id=&#34;deposit-methods-adding-money&#34;&gt;Deposit methods (adding money)
&lt;/h3&gt;&lt;p&gt;With &lt;strong&gt;EQ Bank&lt;/strong&gt;, you can deposit via EFT (link an external account and “pull” funds in), mobile cheque deposit (yes, EQ offers cheque deposit via its app, which Loop and Venn do not), or receive Interac e-Transfers. EQ doesn’t accept cash or in-branch deposits (no branches), so you can’t deposit physical cash or drafts. &lt;strong&gt;Loop&lt;/strong&gt; allows deposits by linking an external bank for ACH/EFT pulls (which take a few days). Loop is working on enabling Interac e-Transfer deposits to your Loop CAD account (planned). &lt;strong&gt;Venn&lt;/strong&gt; similarly can link external accounts for EFT, and it has a clever workaround to fund your account instantly: you can &lt;strong&gt;send yourself an Interac e-Transfer&lt;/strong&gt; to your Venn account (Venn provides you a unique email address to auto-deposit, essentially). This way, you could e-Transfer money from, say, your personal bank or another bank, into Venn within minutes. It’s a nice convenience Loop lacks at the moment.&lt;/p&gt;
&lt;h3 id=&#34;bill-payments-and-cra-taxes&#34;&gt;Bill payments and CRA taxes
&lt;/h3&gt;&lt;p&gt;Only &lt;strong&gt;EQ Bank&lt;/strong&gt; allows outbound bill payments (paying Canadian billers through the Canadian bill payment system). This is useful for things like paying credit card bills, suppliers who have banking set up with billing codes, etc. They even go a step further by enabling &lt;strong&gt;CRA business tax payments&lt;/strong&gt; directly from the account interface. For example, you can make GST/HST remittances or payroll source deduction payments via EQ Bank’s online banking (similar to how one would with a big bank’s business account). Loop and Venn do &lt;strong&gt;not&lt;/strong&gt; have integrated CRA tax payment functionality; you’d have to pay the CRA directly via their Web site, via a third-party or by mailing payments if using those platforms. If you frequently remit taxes, EQ’s built-in support is a time-saver.&lt;/p&gt;
&lt;h3 id=&#34;recurring-and-automated-payments&#34;&gt;Recurring and automated payments
&lt;/h3&gt;&lt;p&gt;Both &lt;strong&gt;Venn&lt;/strong&gt; and &lt;strong&gt;EQ Bank&lt;/strong&gt; support scheduling recurring payments or transfers. You can set up an automatic weekly payment or monthly rent, etc., easily. &lt;strong&gt;Loop&lt;/strong&gt; currently does not have a recurring/scheduled transfer feature (marked as “Planned”). &lt;strong&gt;Venn&lt;/strong&gt; even offers more sophisticated automation on paid plans, like multi-step approvals for payments (useful in larger companies). It also has an &lt;strong&gt;“auto top-up”&lt;/strong&gt; feature where you can maintain a target balance in a sub-account, e.g., automatically transfer funds from your main account to a sub-account if it dips below a threshold (helpful for budgeting). Loop intends to add similar balance automation, but it’s not there yet. &lt;strong&gt;EQ Bank&lt;/strong&gt; doesn’t offer automatic top-ups or any advanced payment automation beyond standard recurring bill payments.&lt;/p&gt;
&lt;p&gt;In summary, &lt;strong&gt;Loop and Venn are far superior for international payments and multi-currency transfers&lt;/strong&gt;, while &lt;strong&gt;EQ Bank covers the basics of domestic payments and adds useful bill/CRA payments&lt;/strong&gt;. If your business is mostly domestic, EQ’s simplicity and free unlimited Interac/EFT may suffice. But if you deal globally, Loop or Venn will be indispensable.&lt;/p&gt;
&lt;h2 id=&#34;card-features-spending-rewards-and-wallets&#34;&gt;Card Features: Spending, Rewards, and Wallets
&lt;/h2&gt;&lt;p&gt;All three platforms take different approaches to &lt;strong&gt;payment cards&lt;/strong&gt; for your business:&lt;/p&gt;
&lt;h3 id=&#34;loop-1&#34;&gt;Loop
&lt;/h3&gt;&lt;p&gt;Loop issues the &lt;strong&gt;Loop Global Visa&lt;/strong&gt; corporate card. This can be debit card (paid out of your account balance) or a true &lt;strong&gt;credit card (corporate card)&lt;/strong&gt;, meaning you get a credit limit and can carry a balance (Loop extends credit based on your business finances). The standout feature is that it’s a &lt;strong&gt;multi-currency Visa card&lt;/strong&gt;: when you spend in USD, EUR, or GBP, it draws from your respective currency balance (if you have funds in those currencies) or from your credit in those currencies. There are &lt;strong&gt;no foreign transaction fees&lt;/strong&gt; on this card for the supported currencies (CAD, USD, EUR, GBP); you can literally travel or make purchases abroad in those currencies with &lt;em&gt;0% FX fee&lt;/em&gt; (big banks typically charge ~2.5% on card purchases). Loop provides both &lt;strong&gt;physical and virtual cards&lt;/strong&gt; (even on the free plan you can have 20 virtual cards for online spending). You can issue cards to employees as well, with spend controls. However, &lt;strong&gt;Loop’s rewards&lt;/strong&gt; are points-based rather than straight cashback. On the free plan, you earn “1× points” per dollar, which effectively is a rewards program but &lt;strong&gt;not cash&lt;/strong&gt;. The points can be redeemed (Loop hasn’t publicly detailed if it’s for statement credits or perks, but there’s no direct cashback on the base plan). Higher Loop plans earn 2× points. It’s a bit complex compared to a simple cashback system. And notably, &lt;strong&gt;Loop’s base plan offers 0% cashback&lt;/strong&gt; in practical terms; the points have some value, but there’s no immediate cash rebate on purchases. If rewards are a priority, consider that.&lt;/p&gt;
&lt;h3 id=&#34;venn-1&#34;&gt;Venn
&lt;/h3&gt;&lt;p&gt;Venn offers a &lt;strong&gt;Venn Mastercard Corporate Card&lt;/strong&gt;, which functions like a debit/charge card linked to your account balance. It is &lt;strong&gt;not prepaid&lt;/strong&gt; in the sense that it’s fully integrated with your Venn account and can be used wherever Mastercard is accepted. Like Loop’s, the Venn card is &lt;strong&gt;multi-currency&lt;/strong&gt;: if you have USD in your account and use the card in the US, it will deduct from your USD balance with no FX fee. If you don’t have that currency, it will convert at Venn’s low FX rate. The &lt;strong&gt;big advantage of Venn’s card&lt;/strong&gt; is its rewards: it gives a flat &lt;strong&gt;1% cashback&lt;/strong&gt; on &lt;strong&gt;all purchases&lt;/strong&gt;, automatically. This cashback is unlimited and applied as real cash (not points), a strong perk for using Venn. For a fintech business card in Canada, 1% back on everything is excellent (few traditional business cards match that without annual fees). Venn provides &lt;strong&gt;unlimited virtual cards&lt;/strong&gt; and free physical cards (one per user; additional physical cards cost $10). You can also set spending limits and category restrictions on each card, which is great for expense management. One limitation: as of now &lt;strong&gt;Venn’s card cannot be added to Apple Pay or Google Pay&lt;/strong&gt; (no mobile wallet support). So you’ll need the physical card on hand for tap payments, etc., whereas Loop’s card &lt;em&gt;can&lt;/em&gt; be added to your phone’s wallet for contactless payments.&lt;/p&gt;
&lt;h3 id=&#34;eq-bank-1&#34;&gt;EQ Bank
&lt;/h3&gt;&lt;p&gt;EQ Bank currently does &lt;strong&gt;not offer any business payment card&lt;/strong&gt;. When you open an EQ Bank Business Account, you have no debit card or credit card associated with that account. This is a significant difference from Loop and Venn. It means you cannot directly spend your EQ business funds in a store or online via card; you’d have to transfer money out to another account to spend, or pay bills electronically. EQ has hinted at working on a business card in the future, but nothing yet. For some businesses, this is a deal-breaker: If you need a business &lt;strong&gt;debit card&lt;/strong&gt; for routine purchases or a &lt;strong&gt;credit card&lt;/strong&gt; for employee spending, EQ Bank alone won’t suffice. You might then pair it with a separate card (or simply choose Loop or Venn which have integrated cards).&lt;/p&gt;
&lt;p&gt;In summary, if having a &lt;strong&gt;versatile business card&lt;/strong&gt; is important, &lt;strong&gt;Loop and Venn are the clear winners&lt;/strong&gt;. Loop’s Visa is great for travel and global spending (no FX fees), and Venn’s Mastercard gives you cash back on everything. They both offer robust expense controls and multiple cards for your team. EQ Bank’s lack of a card is a notable gap.  Though you save on fees elsewhere, you’ll need another solution for card-based spending (which could negate some of the simplicity of banking with EQ only).&lt;/p&gt;
&lt;h2 id=&#34;fees-and-pricing-plans&#34;&gt;Fees and Pricing Plans
&lt;/h2&gt;&lt;p&gt;All three platforms have &lt;strong&gt;no monthly fee&lt;/strong&gt; for their basic offerings; that’s a core appeal of these challengers compared to traditional banks (which often charge $20+ monthly for a business account). However, &lt;strong&gt;Loop and Venn use tiered subscription plans&lt;/strong&gt; to unlock additional features or lower fees, whereas &lt;strong&gt;EQ Bank has only one free tier&lt;/strong&gt; (no paid upgrades, all features included by default).&lt;/p&gt;
&lt;h3 id=&#34;loops-plans&#34;&gt;Loop’s Plans
&lt;/h3&gt;&lt;p&gt;Loop has three plan levels: &lt;strong&gt;Basic ($0/month)&lt;/strong&gt;, &lt;strong&gt;Loop Plus&lt;/strong&gt;, and &lt;strong&gt;Loop Power&lt;/strong&gt;. The Plus and Power plans carry hefty sticker prices if paid monthly ($79 and $299 per month, respectively). Most small businesses will be fine on the free Basic plan, which already gives you multi-currency accounts and cards. The paid plans mainly &lt;strong&gt;reduce your FX fees&lt;/strong&gt; and increase card perks. Specifically, Loop’s FX conversion fee drops from &lt;strong&gt;0.50% on Basic to 0.25% on Plus, and 0.10% on Power&lt;/strong&gt;. Those are &lt;em&gt;extremely&lt;/em&gt; low FX markups; 0.10% is virtually at the interbank rate (great for large volume currency exchange). By comparison, Wise’s well-known FX fee is around 0.43%, so even Loop’s free tier is a tad higher than Wise, but Loop’s top tier undercuts Wise significantly. Loop’s paid plans also increase your card rewards (2× points vs 1×) and come with a higher number of free physical cards and some premium services (like instant deposit of credit card payments). &lt;strong&gt;Important:&lt;/strong&gt; You don’t have to upgrade unless your business would save more in fees than the subscription cost. Many growing businesses might find the $49/month Loop Plus worth it if they do a lot of FX volume, since it halves the FX fee from 0.5% to 0.25%. But if you only occasionally need FX or international payments, you can comfortably stay on free. Loop does &lt;strong&gt;not charge transaction fees&lt;/strong&gt; for day-to-day operations even on the free plan; you get unlimited free transactions (EFTs, wires, etc.), which is very generous.&lt;/p&gt;
&lt;h3 id=&#34;venns-plans&#34;&gt;Venn’s Plans
&lt;/h3&gt;&lt;p&gt;Venn also has three tiers: &lt;strong&gt;Essentials (Free)&lt;/strong&gt;, &lt;strong&gt;Plus ($40/month)&lt;/strong&gt;, and &lt;strong&gt;Pro ($100/month)&lt;/strong&gt;. The &lt;strong&gt;Essentials (free)&lt;/strong&gt; plan has no monthly fee, but unlike Loop, certain transactions have fees on this tier, notably a &lt;strong&gt;$2 fee per outgoing EFT/ACH&lt;/strong&gt; and &lt;strong&gt;$10 per international wire sent&lt;/strong&gt;. For a business with low volume of payments, that might be fine, but if you do many transfers, those $2 fees add up. The paid &lt;strong&gt;Plus&lt;/strong&gt; plan at $40/mo makes all your domestic transfers free (and lowers the international wire fee to $8). It also &lt;strong&gt;lowers the FX conversion fee&lt;/strong&gt; from 0.45% to &lt;strong&gt;0.35%&lt;/strong&gt;. The &lt;strong&gt;Pro&lt;/strong&gt; at $100/mo lowers FX further to &lt;strong&gt;0.25%&lt;/strong&gt;, and further reduces wire fees ($6). Additionally, certain features are gated: for example, &lt;strong&gt;sub-accounts&lt;/strong&gt;: On Essentials you get 5, on Plus you get 10, on Pro unlimited. &lt;strong&gt;User access controls&lt;/strong&gt; (roles/permissions for team members) are only enabled on the paid plans; the free plan allows you to add other owners only. Plus/Pro also add priority support and some advanced automation (rules for accounting, multi-step approvals, etc.). In short, &lt;strong&gt;Venn’s free account is great for trying out or for a very small operation&lt;/strong&gt;, but many businesses will likely need to upgrade to &lt;strong&gt;Plus ($40)&lt;/strong&gt; to avoid nickel-and-dime transaction fees and get multi-user support. The good news is you can start free and only upgrade as needed, and $40/month is still far less than many legacy banks (and could easily pay for itself if you send a lot of EFTs or FX).&lt;/p&gt;
&lt;h3 id=&#34;eq-banks-pricing&#34;&gt;EQ Bank’s Pricing
&lt;/h3&gt;&lt;p&gt;EQ Bank keeps it simple; there is &lt;strong&gt;no monthly fee, period&lt;/strong&gt;, and &lt;strong&gt;most transactions are free&lt;/strong&gt;. You get unlimited free EFTs, free bill payments, and free deposits. The only fees you’d encounter are if you exceed the free Interac e-Transfer limits (more than 50 sent per month) or certain less common actions (like a paper statement by mail, etc., which are optional). There are &lt;strong&gt;no premium tiers&lt;/strong&gt; to pay for as you get everything (that they offer) on the standard account. This simplicity is a big plus for cost-conscious entrepreneurs. &lt;strong&gt;However,&lt;/strong&gt; keep in mind EQ Bank doesn’t offer some of the more advanced or expensive-to-provide features (no foreign wires, no multi-currency, no included international transfer service); those are exactly the things Loop and Venn monetize via their paid plans. So with EQ, it’s “you get what you get for free,” and if you need more exotic services, EQ might not have them at all.&lt;/p&gt;
&lt;p&gt;In summary, &lt;strong&gt;all three are very affordable compared to traditional banks&lt;/strong&gt;. Loop and Venn can be used entirely for free, but they also provide upgrade paths for businesses that need higher tiers of service; you’ll have to weigh the benefits of lower FX fees or more features against the subscription cost. EQ Bank is wonderfully straightforward on pricing (free means free), but it doesn’t have premium add-ons.  If you outgrow what EQ offers, you might find yourself looking at the others anyway.&lt;/p&gt;
&lt;h2 id=&#34;venns-own-venn-vs-loop-comparison-bias-check&#34;&gt;Venn’s Own “Venn vs Loop” Comparison (Bias Check)
&lt;/h2&gt;&lt;p&gt;It’s worth noting that &lt;strong&gt;Venn itself publishes a “Venn vs. Loop” comparison&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://www.venn.ca/resources/venn-vs-loop&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;on its Web site&lt;/a&gt;. This can be a useful read for a quick overview, but keep in mind it is &lt;strong&gt;marketing material created by Venn&lt;/strong&gt;, so it naturally highlights Venn’s advantages and downplays its weaknesses relative to Loop. For example, Venn’s site claims &lt;em&gt;“Venn delivers faster onboarding and more transparent, cost-effective pricing, particularly in FX rates and subscription plans. Additionally, Venn offers actual cashback instead of points…”&lt;/em&gt;. It emphasizes that Venn has a 1% cashback reward versus Loop’s points-based rewards. These points are valid: the &lt;strong&gt;cashback on Venn’s card is a clear perk&lt;/strong&gt; over Loop’s point system, and Venn’s transparency about fees is commendable (they openly list that Loop’s FX is 0.5% vs their 0.45% on free tier, etc.).&lt;/p&gt;
&lt;p&gt;However, the Venn comparison is of course &lt;strong&gt;biased in Venn’s favor&lt;/strong&gt;. For instance, it calls Venn’s FX rates “industry-leading” while characterizing Loop’s as “markups”, even though in reality Loop’s top-tier 0.10% rate is lower than Venn’s best 0.25%. The Venn write-up also touts features like accounting integrations and automation that Venn has and Loop purportedly lacks or has “limited”. In short, &lt;strong&gt;Venn’s comparison is a helpful marketing snapshot, but take it with a grain of salt&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The truth is both &lt;strong&gt;Loop and Venn are strong platforms&lt;/strong&gt; with slightly different focuses: &lt;strong&gt;Loop&lt;/strong&gt; is very focused on &lt;em&gt;cross-border banking, FX, and credit&lt;/em&gt; (e.g., offering working capital up to $1M and no-fee international payments), whereas &lt;strong&gt;Venn&lt;/strong&gt; pitches itself as an &lt;em&gt;all-in-one financial platform&lt;/em&gt; for businesses, with features like expense management, accounting sync, invoicing, and even investment products. Depending on your business’s needs, one may suit you better. If you value &lt;strong&gt;cashback and an integrated bookkeeping/payment stack&lt;/strong&gt;, Venn is appealing. If you value &lt;strong&gt;lowest possible FX fees and free unlimited global transfers&lt;/strong&gt;, Loop is hard to beat. And Venn’s own comparison, while informative, understandably underscores Venn’s strengths so also look at independent reviews or firsthand trials.&lt;/p&gt;
&lt;h2 id=&#34;other-alternatives-a-note-on-wise-transferwise&#34;&gt;Other Alternatives: A Note on Wise (TransferWise)
&lt;/h2&gt;&lt;p&gt;You might be wondering about &lt;strong&gt;Wise&lt;/strong&gt; (formerly TransferWise), since it’s popular for international business banking. Wise isn’t included in our main comparison because it’s &lt;em&gt;not a Canadian bank or credit union&lt;/em&gt;; it’s a London-based financial tech company. However, they do offer a Business account that many Canadian businesses use alongside their local bank. With Wise, you can hold and manage funds in &lt;strong&gt;dozens of currencies&lt;/strong&gt;, and you get local bank details in several countries (US, UK, Eurozone, etc.), somewhat like Loop and Venn provide. Wise’s currency conversion fees are very competitive, about &lt;strong&gt;0.43%&lt;/strong&gt; on conversions, which often beats regular banks. They also provide a &lt;strong&gt;debit card&lt;/strong&gt; (Mastercard) that lets you spend from your Wise balances and should work globally anywhere Mastercard is accepted. (However, I have found that it &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; work everywhere, which is why I started looking for other options.)  In fact, many entrepreneurs use Wise’s card when traveling or paying overseas, because it automatically uses the local currency balance or converts at the low Wise rate with no extra foreign transaction markup.&lt;/p&gt;
&lt;p&gt;That said, &lt;strong&gt;Wise is not a full replacement for a Canadian business bank account&lt;/strong&gt;. You &lt;strong&gt;can’t do Interac e-Transfers&lt;/strong&gt; with Wise, you can’t pay Canadian bills or taxes through it, the payment card doesn&amp;rsquo;t actually work everywhere, and your Wise balance isn’t CDIC-insured (though Wise keeps client funds in safeguarded accounts). Typically, a Canadian business might use Wise &lt;em&gt;in addition&lt;/em&gt; to one of the accounts above.  For example, the might use Wise for a specific international project or vendor payments, but still maintain a Canadian-dollar account like Loop/Venn/EQ for domestic needs. Wise is an excellent specialist tool for FX and global transactions (in fact, Loop and Venn sometimes &lt;a class=&#34;link&#34; href=&#34;https://help.venn.ca/en/articles/9236395-does-venn-offer-better-foreign-exchange-fx-rates-than-wise-loop-and-other-banks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;compare themselves to Wise on rates&lt;/a&gt;), but since Wise isn’t Canadian-owned or focused, we centered our comparison on Loop, Venn, and EQ Bank, which are all Canadian-focused solutions.&lt;/p&gt;
&lt;h2 id=&#34;conclusion-which-challenger-bank-to-choose&#34;&gt;Conclusion: Which Challenger Bank to Choose?
&lt;/h2&gt;&lt;p&gt;Each of these modern business banking options brings something different to the table, and the “best” choice really depends on your company’s priorities.&lt;/p&gt;
&lt;h3 id=&#34;eq-bank-2&#34;&gt;EQ Bank
&lt;/h3&gt;&lt;p&gt;EQ Bank is ideal for &lt;strong&gt;simple, fee-free banking&lt;/strong&gt; if your needs are mostly domestic. You’ll earn a high interest rate on your balance, pay no fees, and enjoy unlimited transactions within Canada. It’s perfect for sole proprietors or small businesses that just need a basic account to send/receive money in CAD, pay bills, and maybe stash some savings, all while avoiding bank fees. The downsides are the lack of a card and no multi-currency or advanced features. EQ Bank is like a high-interest business chequing/savings hybrid that’s super easy to use and saves you money, as long as you don’t need bells and whistles.&lt;/p&gt;
&lt;h3 id=&#34;loop-2&#34;&gt;Loop
&lt;/h3&gt;&lt;p&gt;Loop shines if your business has a &lt;strong&gt;global footprint or significant foreign currency needs&lt;/strong&gt;. It truly enables a small business to &lt;em&gt;bank like a local abroad&lt;/em&gt; by giving you local USD, EUR, GBP accounts and a multi-currency card. The absence of wire fees and ultra-low FX rates on higher plans can save &lt;strong&gt;tens of thousands of dollars&lt;/strong&gt; for businesses that do large international transactions. Loop is also great if you want a &lt;strong&gt;credit card for your business&lt;/strong&gt;,  especially one with no FX fees on spend. Keep in mind, Loop is best for corporations (their onboarding might be slower if you’re a very new or small sole prop) and it currently lacks Interac e-Transfers which are ubiquitous in Canada. If you can live without Interac for now (or use EQ/another account as a workaround for e-Transfers), Loop offers tremendous value for cross-border finance. It’s like a modern alternative to having a USD account at RBC plus a EUR account at HSBC, etc., all consolidated in one platform. Many tech startups and e-commerce companies love Loop for these reasons.&lt;/p&gt;
&lt;h3 id=&#34;venn-2&#34;&gt;Venn
&lt;/h3&gt;&lt;p&gt;Venn is a compelling choice for a business that wants &lt;strong&gt;an all-in-one financial platform&lt;/strong&gt; and plans to grow into it. It has a broad feature set (global accounts, corporate card, invoicing, even investments) and is building a full ecosystem (expense management, accounting automation, etc.). The 1% cashback on the Venn card is a steady perk that essentially gives you back some money on every business purchase, essentially helping offset the subscription if you do enough volume. Venn’s slightly higher FX fees than Loop are still way better than banks, and everything is transparent. One thing to consider is cost: if you need multiple users or lots of transactions, you’ll likely be on the $40/month plan at least. But even at $40 or $100 a month, Venn might replace several other tools (it could handle international payments, corporate cards, &lt;em&gt;and&lt;/em&gt; some accounting tasks in one). &lt;strong&gt;Venn is a strong pick for a growing startup or SMB&lt;/strong&gt; that wants to streamline finances digitally and is okay with a monthly software-as-a-service (SaaS) fee for a better experience. It’s also an obvious alternative if you find Loop’s points/rewards or lack of interest a turn-off; with Venn you get cash back and can even earn interest through GICs on spare cash.&lt;/p&gt;
&lt;p&gt;In many cases, &lt;strong&gt;a combination might serve you best&lt;/strong&gt;. Since there’s no cost to open these accounts, some businesses use &lt;strong&gt;EQ Bank&lt;/strong&gt; to park cash (earning interest) and handle Canadian transactions, while also using &lt;strong&gt;Loop or Venn&lt;/strong&gt; for their card and global banking needs. That way you get the best of both: no-fee domestic banking plus advanced FX and card features. Just be mindful of keeping bookkeeping straight if using multiple accounts.&lt;/p&gt;
&lt;p&gt;The emergence of Loop, Venn, EQ Bank (and others like Wealthsimple, Tangerine, Neo, etc.) signals a new era of banking in Canada, which is now helpful for businesses. The common theme is &lt;strong&gt;zero fees, flexibility, and fintech innovation&lt;/strong&gt;, which is a refreshing change from the old-school big banks with their paperwork and charges. By evaluating what matters most for your business, be it saving on foreign exchange, earning interest, getting cashback, or simply avoiding fees, you can choose the platform that aligns best. And since all have free tiers, you can even try them to see which interface and service you prefer. One thing is certain: Canadian business owners finally have viable alternatives to the Big 5, and that competition can only be a good thing for entrepreneurs.&lt;/p&gt;
&lt;h2 id=&#34;take-them-for-a-spin&#34;&gt;Take Them for a Spin
&lt;/h2&gt;&lt;p&gt;If you&amp;rsquo;re ready to experiment and set up one or more of these accounts yourself, you can use my referral codes to get started.  We&amp;rsquo;ll both get something back for doing so.  However, these are only available for Loop and Venn because EQ Bank doesn&amp;rsquo;t offer such a program.  You can find links for these on the last row of the comparison table above.&lt;/p&gt;
&lt;h2 id=&#34;corrections-and-updates&#34;&gt;Corrections and Updates
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;d like to keep this comparison as accurate and current as possible, but fintech tools evolve quickly. If you spot any errors or want to share updates (e.g. new features, pricing changes, eligibility details) I welcome your corrections. Feel free to reach out and help keep this resource reliable. Thanks for reading!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Want to Run Drupal in Kubernetes? Try Our New Terraform Module</title>
        <link>https://colan.pro/blog/drubernetes-terraform-module-for-drupal-in-kubernetes-clusters/</link>
        <pubDate>Sun, 13 Jul 2025 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drubernetes-terraform-module-for-drupal-in-kubernetes-clusters/</guid>
        <description>&lt;img src="https://colan.pro/blog/drubernetes-terraform-module-for-drupal-in-kubernetes-clusters/drubernetes-terraform-kubernetes-drupal.png" alt="Featured image of post Want to Run Drupal in Kubernetes? Try Our New Terraform Module" /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;This article was &lt;a class=&#34;link&#34; href=&#34;https://backupscale.com/posts/drubernetes-terraform-module-for-kubernetes-clusters/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;originally published on the BackUpScale blog&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background
&lt;/h2&gt;&lt;p&gt;Our customer dashboard, which will soon be used for managing subscriptions to our backup service (and not just newsletters and our contact form, as we&amp;rsquo;re doing now), is built on the Drupal data management framework.  Until now, we&amp;rsquo;ve been hosting it with a company that specializes in hosting very specific types of applications, like Drupal.  This wasn&amp;rsquo;t working for us because our service is running in our Kubernetes cluster at a cloud service provider that specializes in managed Kubernetes hosting, which let&amp;rsquo;s us run whatever applications we want, and configure them however we need.  The challenge was getting the dashboard to communicate securely with our other applications.&lt;/p&gt;
&lt;p&gt;It needs to communicate with our back-end systems in the Kubernetes cluster to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;send requests from customers to provision services,&lt;/li&gt;
&lt;li&gt;configure customer accounts, and&lt;/li&gt;
&lt;li&gt;receive status information from back-end services to create log entries that users can see in their accounts.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;why-the-old-approach-broke-down&#34;&gt;Why the old approach broke down
&lt;/h2&gt;&lt;p&gt;In order for things to work with the old set up, we&amp;rsquo;d have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;expose internal applications to the Internet (so the dashboard site could access them), and&lt;/li&gt;
&lt;li&gt;add additional layers of security to the communications to ensure privacy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We didn&amp;rsquo;t feel as confident with this set-up as moving everything into our private Kubernetes network, which protects all of our services with a single firewall.  Keeping non-public facing services within that network ensures that they&amp;rsquo;re not accessible by anyone on the greater Internet (except our staff using the company VPN), which ensures greater security and privacy for our users.&lt;/p&gt;
&lt;p&gt;In order to make the change, we needed to be able to run a Drupal site within Kubernetes.  Given that Drupal is a popular framework, and Kubernetes is a popular container orchestration system, we assumed that there would be good options for putting them together using open-source infrastructure as code (IaC) to handle the automated provisioning (we automate everything here).  However, we weren&amp;rsquo;t able to find anything that could help us.&lt;/p&gt;
&lt;h2 id=&#34;evaluated-options&#34;&gt;Evaluated options
&lt;/h2&gt;&lt;p&gt;We explored the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://artifacthub.io/packages/helm/bitnami/drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bitnami&amp;rsquo;s Helm chart&lt;/a&gt; (&lt;a class=&#34;link&#34; href=&#34;https://github.com/bitnami/charts/issues/5434#issuecomment-1001165522&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;no longer supported as of 2021&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/geerlingguy/drupal-operator&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Jeff Geerling&amp;rsquo;s Drupal Operator&lt;/a&gt; (&lt;a class=&#34;link&#34; href=&#34;https://github.com/geerlingguy/drupal-operator/issues/28#issuecomment-2585584277&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;no longer supported as of early 2025&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Bitnami Helm chart did at least one very strange thing: It was placing the Drupal code files on the persistent volume instead of placing them in the container image.  We wanted the Drupal code (or at least the Composer files that build it along with any custom code) to be version controlled with Git.  When we tried to work around this, &lt;a class=&#34;link&#34; href=&#34;https://github.com/bitnami/charts/issues/8302&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;they made it very difficult to make these changes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Jeff Geerling simply stopped recommending his earlier approach (except for potentially hosting many sites on a hosting platform), and said that he currently uses his own Kubernetes primitives.  So we took that idea, and expanded on it to build a fairly complete solution.  Once we had something that worked for us, we believed we could make it generic enough to make it available to everyone else.  So that&amp;rsquo;s what we did.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://colan.pro/blog/drubernetes-terraform-module-for-drupal-in-kubernetes-clusters/moving-dashboard-inside-cluster.png&#34;
	width=&#34;665&#34;
	height=&#34;592&#34;
	srcset=&#34;https://colan.pro/blog/drubernetes-terraform-module-for-drupal-in-kubernetes-clusters/moving-dashboard-inside-cluster_hu5482656448936507701.png 480w, https://colan.pro/blog/drubernetes-terraform-module-for-drupal-in-kubernetes-clusters/moving-dashboard-inside-cluster_hu503231741745929296.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;diagram&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;112&#34;
		data-flex-basis=&#34;269px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;This move eliminated two Internet-facing endpoints and let us apply a single network-policy layer to all microservices.  Additionally, running inside the cluster removes a public load balancer, and shrinks latency.&lt;/p&gt;
&lt;h2 id=&#34;meet-drubernetes&#34;&gt;Meet &amp;ldquo;Drubernetes&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Because we automate all of our infrastructure with Terraform, we just released &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/modules/BackUpScale/drupal/kubernetes/latest&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drubernetes&lt;/a&gt;, a new module in the Terraform Registry, which provisions Drupal onto a generic Kubernetes cluster.  It shouldn&amp;rsquo;t matter where your cluster is, who&amp;rsquo;s managing it for you, or if you&amp;rsquo;re managing it yourself on your own hardware.  We wanted to provide something standardized that everyone can use and build from.&lt;/p&gt;
&lt;h2 id=&#34;contribute&#34;&gt;Contribute
&lt;/h2&gt;&lt;p&gt;Contributions are welcome!  Please try it, and provide any feedback that you may have.  The project is &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/backupscale/drubernetes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;hosted on Gitlab.com&lt;/a&gt;, and any issues can be opened &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/backupscale/drubernetes/-/boards&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;from the board&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;As always, if you have questions or feedback, feel free to &lt;a class=&#34;link&#34; href=&#34;https://backupscale.com/community/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;reach out&lt;/a&gt;. We appreciate your support and can’t wait to bring you the next chapter of BackupScale.&lt;/em&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>From DevOps Headaches to Seamless Onboarding: How Dropping Chocolatey Made DDEV the Perfect Fit for a Client&#39;s Drupal Team</title>
        <link>https://colan.pro/blog/dropping-chocolatey-for-ddev-on-windows-drupal-development/</link>
        <pubDate>Thu, 03 Jul 2025 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/dropping-chocolatey-for-ddev-on-windows-drupal-development/</guid>
        <description>&lt;img src="https://colan.pro/blog/dropping-chocolatey-for-ddev-on-windows-drupal-development/simpler-drupal-dev-on-windows-with-ddev.png" alt="Featured image of post From DevOps Headaches to Seamless Onboarding: How Dropping Chocolatey Made DDEV the Perfect Fit for a Client&#39;s Drupal Team" /&gt;&lt;h2 id=&#34;tldr&#34;&gt;TL;DR
&lt;/h2&gt;&lt;p&gt;After watching my enterprise client&amp;rsquo;s Drupal developers lose hours every week wrestling with raw Docker Compose for local development, I championed a switch to &lt;strong&gt;DDEV&lt;/strong&gt;, the open‑source tool that gives &lt;em&gt;“container superpowers with zero required Docker skills”&lt;/em&gt; (&lt;a class=&#34;link&#34; href=&#34;https://ddev.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ddev.com&lt;/a&gt;). One of the snags on their Windows laptops was the Chocolatey package manager, whose  install path clashed with locked‑down corporate security policies. Working with DDEV maintainer Randy Fay, I removed the Chocolatey dependency, paving the way for a leaner installer that shipped in version 1.24.5. Development team members now onboard much quicker, and leadership can point to measurable productivity gains.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;the-starting-point-docker-compose-drag&#34;&gt;The Starting Point: Docker Compose Drag
&lt;/h2&gt;&lt;p&gt;My client&amp;rsquo;s legacy workflow relied on a bespoke Docker Compose stack. Developers routinely diverted time to babysit containers as well as copying their work in and out, instead of writing code.  This echeos industry findings that more than &lt;a class=&#34;link&#34; href=&#34;https://www.cortex.io/report/the-2024-state-of-developer-productivity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;58% of engineers lose 5‑plus hours per week to “unproductive work”&lt;/a&gt;.  This DevOps overhead impacts their developer experience (DX), which is a distraction from their actual work.&lt;/p&gt;
&lt;h2 id=&#34;enter-ddev&#34;&gt;Enter DDEV
&lt;/h2&gt;&lt;p&gt;DDEV abstracts all that Docker plumbing with simple commands (e.g. &lt;code&gt;ddev start&lt;/code&gt;, &lt;code&gt;ddev stop&lt;/code&gt;) while still running everything locally. Its promise, &lt;em&gt;“environments in minutes, multiple concurrent projects, and less time to deployment”&lt;/em&gt;, resonated immediately.&lt;/p&gt;
&lt;h3 id=&#34;why-it-mattered-for-drupal&#34;&gt;Why It Mattered for Drupal
&lt;/h3&gt;&lt;p&gt;A Drupal codebase is never just PHP; it drags along Composer, Drush, front‑end toolchains, and database snapshots. DDEV’s predefined &lt;strong&gt;Drupal preset&lt;/strong&gt; provides a reproducible stack with Nginx/Apache, MariaDB, and Mailhog out of the box.&lt;/p&gt;
&lt;h2 id=&#34;a-windows-speedbump-called-chocolatey&#34;&gt;A Windows Speed‑Bump Called Chocolatey
&lt;/h2&gt;&lt;p&gt;The developers work on locked‑down Windows laptops. DDEV’s install script used the &lt;strong&gt;Chocolatey&lt;/strong&gt; package manager, which corporate policies block from writing to its default location. Workarounds involved various hurdles, exactly the sort of DevOps toil they wanted to eliminate.&lt;/p&gt;
&lt;h2 id=&#34;collaborating-upstream-issue-6636--pr-7049&#34;&gt;Collaborating Upstream: Issue #6636 → PR #7049
&lt;/h2&gt;&lt;p&gt;While in research mode, I discovered &lt;a class=&#34;link&#34; href=&#34;https://github.com/ddev/ddev/issues/6636&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Issue #6636&lt;/a&gt;, maintainers themselves wanted to drop Chocolatey but hadn’t had the bandwidth to do so. I volunteered a pull request that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;removed Chocolatey from the installation process, and&lt;/li&gt;
&lt;li&gt;no longer required an Administrator Powershell; an unprivileged user could install it in a terminal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The patch was merged on &lt;a class=&#34;link&#34; href=&#34;https://github.com/ddev/ddev/pull/7049#event-17207866881&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;April 10, 2025&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;release-v1245-goodbye-chocolatey&#34;&gt;Release v1.24.5: Goodbye Chocolatey
&lt;/h2&gt;&lt;p&gt;A month later, the change landed in &lt;a class=&#34;link&#34; href=&#34;https://github.com/ddev/ddev/releases/tag/v1.24.5&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;v1.24.5&lt;/a&gt; with a shout‑out in the release notes: &lt;em&gt;“Chocolatey removed from automated Windows installation scripts. Thanks to &lt;a class=&#34;link&#34; href=&#34;https://github.com/colans&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;@colans&lt;/a&gt;.”&lt;/em&gt;  It&amp;rsquo;s now simpler for Windows developers to install DDEV, and they don&amp;rsquo;t have to be an administrator.&lt;/p&gt;
&lt;h2 id=&#34;business-case-as-pitched-to-leadership&#34;&gt;Business Case (as pitched to leadership)
&lt;/h2&gt;&lt;p&gt;&lt;em&gt;“Container superpowers with zero required Docker skills”&lt;/em&gt; isn’t just marketing. Here’s the quantified rationale I presented:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Zero Docker config&lt;/strong&gt;: &lt;code&gt;ddev start&lt;/code&gt; replaces hand‑rolled Compose files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No central registry maintenance&lt;/strong&gt;: Images build locally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Host‑level commands&lt;/strong&gt;: &lt;code&gt;ddev drush status&lt;/code&gt; or &lt;code&gt;ddev composer install&lt;/code&gt; without &lt;code&gt;docker exec&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unified file system&lt;/strong&gt;: The code lives on the host, eliminating copy‑in/out cycles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Safe rebuilds&lt;/strong&gt;: Deleting containers never loses work.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always‑on Git&lt;/strong&gt;: &lt;code&gt;blame&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;, and &lt;code&gt;branch&lt;/code&gt; with the active code without stepping into the container.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;First‑class Composer&lt;/strong&gt;: Composer‑managed Drupal is just a &lt;code&gt;ddev composer require&lt;/code&gt; away.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;outcomes&#34;&gt;Outcomes
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Onboarding time&lt;/strong&gt; dropped from half a day (or more) to an hour (or less).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Additonal support&lt;/strong&gt; for broken sandboxes fell to nearly zero.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Developers now focus on development&lt;/strong&gt;, not troubleshooting containers, or moving code in and out of them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;gratitude&#34;&gt;Gratitude
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;d like to thank &lt;a class=&#34;link&#34; href=&#34;https://github.com/rfay&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Randy Fay&lt;/a&gt; for prompt code reviews, patient feedback, and for shepherding the change into a release.&lt;/p&gt;
&lt;h2 id=&#34;ready-to-try&#34;&gt;Ready to Try?
&lt;/h2&gt;&lt;p&gt;Head to the official DDEV installation documentation and give it a spin.  And if you&amp;rsquo;re stuck on Windows, it&amp;rsquo;s now much easier to install.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Got Automated Tests? Stick with Container-Friendly Software</title>
        <link>https://colan.pro/blog/containerization-for-automated-tests/</link>
        <pubDate>Wed, 19 Feb 2025 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/containerization-for-automated-tests/</guid>
        <description>&lt;img src="https://colan.pro/blog/containerization-for-automated-tests/DALL%C2%B7E%202025-02-18%2023.54.09%20-%20A%20wide%20futuristic%20scene%20showing%20a%20DevOps%20pipeline%20for%20automated%20testing.%20The%20environment%20features%20containerized%20microservices%20%28represented%20by%20transpar.webp" alt="Featured image of post Got Automated Tests? Stick with Container-Friendly Software" /&gt;&lt;p&gt;Modern DevOps pipelines rely heavily on automated testing. Ideally, each new code commit kicks off a sequence of tests in an environment that mirrors production—ensuring that issues are caught early, and deployment remains reliable. With container technology, it’s easier than ever to spin up temporary test environments that replicate production exactly, run your tests in isolation, then tear them down once done.&lt;/p&gt;
&lt;p&gt;However, when you are forced to integrate closed-source, SaaS-based software that &lt;strong&gt;cannot&lt;/strong&gt; be containerized, the smoothness of your CI/CD pipeline can suffer. Below, we’ll explore the pros of container-based testing, the complexities of closed-source SaaS, and a range of strategies—from spinning up new SaaS instances on demand to using mock services—to handle these challenges effectively.&lt;/p&gt;
&lt;h2 id=&#34;why-container-friendly-dependencies-are-ideal&#34;&gt;&lt;strong&gt;Why Container-Friendly Dependencies Are Ideal&lt;/strong&gt;
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ephemeral Environments&lt;/strong&gt;&lt;br&gt;
Containers allow you to spin up a clean environment for each test. You install your application stack, clone the branch under test, run tests, and then the containers disappear—ensuring no test data contaminates subsequent runs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consistency and Reproducibility&lt;/strong&gt;&lt;br&gt;
Container images can be versioned and shared, ensuring that every pipeline (and every developer) is using the exact same setup.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;br&gt;
Container orchestration systems (like Kubernetes or Docker Swarm) can spin up and tear down test environments at scale, handling parallel test executions efficiently.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduced “Works on My Machine” Issues&lt;/strong&gt;&lt;br&gt;
By relying on Docker images that define system-level dependencies, you remove guesswork from platform variations (e.g., different OS versions, missing libraries, etc.).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;the-problem-closed-source-saas-you-cant-containerize&#34;&gt;&lt;strong&gt;The Problem: Closed-Source SaaS You Can’t Containerize&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;If your organization relies on SaaS or closed-source tools that cannot be run inside a container, it complicates your testing pipeline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No direct control&lt;/strong&gt; over the external environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Licensing or security constraints&lt;/strong&gt; may restrict how often you can spin up new instances.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Potential concurrency conflicts&lt;/strong&gt; if multiple test runs share the same persistent SaaS instance, leading to data contamination or mismatched configurations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nonetheless, businesses often can’t simply ditch such tooling overnight. Below are strategies to accommodate closed-source SaaS within otherwise container-based CI/CD pipelines.&lt;/p&gt;
&lt;h2 id=&#34;three-core-strategies-for-dealing-with-non-containerizable-saas&#34;&gt;&lt;strong&gt;Three Core Strategies for Dealing with Non-Containerizable SaaS&lt;/strong&gt;
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ephemeral SaaS Instances Per Test Run&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: Your CI pipeline dynamically creates a new SaaS instance for every test run, configures it, runs tests, then destroys it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Guaranteed isolation across test runs (no data collision).&lt;/li&gt;
&lt;li&gt;Reflects the ephemeral nature of containerized open-source solutions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Potentially higher cost if the vendor charges per instance or usage.&lt;/li&gt;
&lt;li&gt;Slower pipeline if instance provisioning is lengthy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A Dedicated (Shared) SaaS Instance, Reset Between Runs&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: You keep one or a few permanent instances of the SaaS for testing. After each run, the environment is reset to a baseline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Avoids spinning up new SaaS instances each time.&lt;/li&gt;
&lt;li&gt;Potentially lower cost and faster test startup.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Risk of data contamination if resets aren’t perfect.&lt;/li&gt;
&lt;li&gt;If tests can’t run in parallel, queued runs might cause a bottleneck.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A Dedicated SaaS Instance Using Unique Identifiers&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: Each test run or source (e.g., branch, pull request) is assigned a unique ID. All data in the SaaS is tagged with that ID, preventing collisions among simultaneous tests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Enables parallel test runs without interfering data.&lt;/li&gt;
&lt;li&gt;No need to spin up new SaaS instances if the vendor charges per environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Requires robust tagging logic in your tests and application code.&lt;/li&gt;
&lt;li&gt;Configuration differences between test runs become complicated—different versions might need separate instances anyway.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;additionaladvanced-approaches&#34;&gt;&lt;strong&gt;Additional/Advanced Approaches&lt;/strong&gt;
&lt;/h2&gt;&lt;h3 id=&#34;1-use-stubs-or-mocks-for-partial-testing&#34;&gt;1. Use Stubs or Mocks for Partial Testing
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: Instead of hitting the actual SaaS, you create a mocked or stubbed version of the external service’s API. Your application interacts with this mock during tests, which returns predictable responses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Much faster and cheaper test cycles—mocks don’t require an external service.&lt;/li&gt;
&lt;li&gt;You avoid concurrency issues, since the mock is purely local to the test environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;You lose true end-to-end coverage. While you can &lt;strong&gt;unit test&lt;/strong&gt; and &lt;strong&gt;integration test&lt;/strong&gt; the part you’re mocking separately, &lt;strong&gt;you don’t see how everything works together in a real-world environment.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Requires diligence to keep your mock’s behavior in sync with the vendor’s real API changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Mocks and stubs are great to cover the bulk of your test scenarios quickly (especially early in your pipeline). However, you still need to run &lt;strong&gt;some&lt;/strong&gt; end-to-end tests against the real SaaS instance for final validation.&lt;/p&gt;
&lt;h3 id=&#34;2-vendor-provided-sandbox-or-testing-environments&#34;&gt;2. Vendor-Provided Sandbox or Testing Environments
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: Some SaaS vendors offer specialized “sandbox” instances that mimic production but have no direct effect on live data. They may offer test licenses or allow ephemeral environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Isolated from your actual production instance—reduces risk of messing up real data.&lt;/li&gt;
&lt;li&gt;May include features for easier resets or data seeding.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Not all vendors provide this, or it may cost extra.&lt;/li&gt;
&lt;li&gt;You might still face concurrency or versioning limitations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: If your vendor supports a sandbox environment, explore whether you can automate the creation/reset of these sandboxes within your pipeline.&lt;/p&gt;
&lt;h3 id=&#34;3-hybrid-approach-containers-for-your-stack--shared-saas&#34;&gt;3. Hybrid Approach: Containers for Your Stack + Shared SaaS
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: You containerize everything else (databases, applications, etc.) and rely on a single shared SaaS instance for the parts you can’t containerize.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Retains most benefits of ephemeral containers for your primary app components.&lt;/li&gt;
&lt;li&gt;Less overhead than spinning up multiple SaaS instances.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;You still have to manage concurrency or data collision issues on the SaaS side.&lt;/li&gt;
&lt;li&gt;Potential version/config mismatches if your code requires different SaaS configurations in different branches.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: This approach is common because it strikes a balance between ephemeral containers and the practicality of a single external SaaS environment.&lt;/p&gt;
&lt;h3 id=&#34;4-multi-stage-layered-testing&#34;&gt;4. Multi-Stage (Layered) Testing
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: Break down tests into stages, focusing first on unit and integration tests (often using mocks or local containers) and then following up with a smaller set of full end-to-end tests that hit the actual SaaS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Fast feedback loop for the majority of tests.&lt;/li&gt;
&lt;li&gt;Minimizes expensive calls to SaaS or the complexity of ephemeral SaaS instances.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Requires more complex CI/CD orchestration: you need a pipeline that handles multiple stages and merges results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: A layered test approach can speed up development while still ensuring that at least some tests verify the real SaaS integration.&lt;/p&gt;
&lt;h3 id=&#34;5-negotiate-better-container-support-or-testing-licenses-from-your-vendor&#34;&gt;5. Negotiate Better Container Support or Testing Licenses from Your Vendor
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What It Is&lt;/strong&gt;: Push your SaaS provider for a container-friendly version or a specialized testing license that allows ephemeral usage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Could achieve a setup very close to fully containerized environments.&lt;/li&gt;
&lt;li&gt;Reduces friction and complexities in your DevOps pipeline.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Some vendors may be unwilling or unable to provide containerized distributions.&lt;/li&gt;
&lt;li&gt;Negotiations might require more expense or long-term commitments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: If your application depends heavily on a particular SaaS, it might be worth investing in a conversation with the vendor about containerization or improved testing provisions.&lt;/p&gt;
&lt;h2 id=&#34;final-thoughts&#34;&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prefer Container-Friendly Software&lt;/strong&gt;&lt;br&gt;
Whenever possible, choose tools that can be run in containers. This keeps your CI/CD process straightforward, consistent, and fully ephemeral.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Assess SaaS Vendors Carefully&lt;/strong&gt;&lt;br&gt;
If you can’t containerize a critical dependency, at least check whether the vendor supports sandbox environments, easy resets, or ephemeral provisioning.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Combine Approaches&lt;/strong&gt;&lt;br&gt;
In practice, most teams use a combination of mocking/stubbing, ephemeral containerized components, and partial end-to-end SaaS integration tests. This layered approach often balances speed, cost, and thorough coverage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manage Data Collisions&lt;/strong&gt;&lt;br&gt;
If sharing a single SaaS instance, ensure you reset appropriately or use unique identifiers to segregate test data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consider Long-Term Roadmaps&lt;/strong&gt;&lt;br&gt;
Over time, aim to reduce dependencies on tools that cannot be containerized. Even if it’s not immediate, planning for more portable and container-compatible solutions in the future can pay off in smoother, faster pipelines and fewer operational headaches.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Ultimately,&lt;/strong&gt; the moral of the story remains: &lt;strong&gt;avoid using software you can’t run in containers whenever possible.&lt;/strong&gt; If you’re stuck with non-containerizable SaaS, invest in thoughtful workarounds—whether that’s mocking, ephemeral instances, dedicated instances with resets, or unique IDs—to keep your CI/CD pipelines efficient and reliable.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>A Comparison of Managed Kubernetes Providers Without Egress Fees</title>
        <link>https://colan.pro/blog/comparison-of-managed-kubernetes-providers-without-egress-fees/</link>
        <pubDate>Sun, 27 Oct 2024 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/comparison-of-managed-kubernetes-providers-without-egress-fees/</guid>
        <description>&lt;img src="https://colan.pro/blog/comparison-of-managed-kubernetes-providers-without-egress-fees/DALL%C2%B7E%202024-10-05%2014.20.19%20-%20Multiple%20instances%20of%20the%20Kubernetes%20logo,%20including%20the%20hexagon%20shape%20and%20stylized%20ship.webp" alt="Featured image of post A Comparison of Managed Kubernetes Providers Without Egress Fees" /&gt;&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;When it comes to deploying production-ready Kubernetes clusters, &lt;a class=&#34;link&#34; href=&#34;../hidden-costs-of-cloud-egress-fees&#34; &gt;egress fees can be a hidden cost that quickly adds up&lt;/a&gt;. Major cloud providers like AWS, Google Cloud, and Azure are known for charging these fees, making it harder to predict monthly expenses, send data to other service providers, and ultimately migrate your data elsewhere. Some managed Kubernetes providers, however, offer a more transparent pricing model by eliminating egress fees altogether. In this article, we&amp;rsquo;ll compare four such providers: &lt;a class=&#34;link&#34; href=&#34;https://www.scaleway.com/en/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Scaleway&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://upcloud.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Upcloud&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.civo.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Civo&lt;/a&gt;, and &lt;a class=&#34;link&#34; href=&#34;https://serverspace.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Server Space&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All four providers offer managed Kubernetes, which simplifies cluster maintenance and scalability. However, there are differences in their feature sets and usability, which we’ll explore in more detail in the cost comparison section.&lt;/p&gt;
&lt;h2 id=&#34;criteria-for-comparison&#34;&gt;Criteria for Comparison
&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s take a look at the data, and then dig into each feature below the table.&lt;/p&gt;
&lt;h2 id=&#34;feature-comparison&#34;&gt;Feature Comparison
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Feature&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Scaleway&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Upcloud&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Civo&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Server Space&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Data centre locations&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;France, Netherlands, Poland&lt;/td&gt;
          &lt;td&gt;Various US, Various Europe, Singapore, Australia&lt;/td&gt;
          &lt;td&gt;Germany, UK, US&lt;/td&gt;
          &lt;td&gt;Canada, US, Brazil, Netherlands, Turkey, Kazakhstan, UAE&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;ReadWriteMany?&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Terraform support?&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Incomplete&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Cluster provisioning speed&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;7 minutes&lt;/td&gt;
          &lt;td&gt;?&lt;/td&gt;
          &lt;td&gt;2 minutes&lt;/td&gt;
          &lt;td&gt;?&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Years in business&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;25&lt;/td&gt;
          &lt;td&gt;12&lt;/td&gt;
          &lt;td&gt;6&lt;/td&gt;
          &lt;td&gt;5&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Service level agreement (SLA)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;99.50%&lt;/td&gt;
          &lt;td&gt;100.00%&lt;/td&gt;
          &lt;td&gt;99.95%&lt;/td&gt;
          &lt;td&gt;99.90%&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Headquarters&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Paris, France&lt;/td&gt;
          &lt;td&gt;Helsinki, Finland&lt;/td&gt;
          &lt;td&gt;London, UK&lt;/td&gt;
          &lt;td&gt;Amsterdam, Netherlands&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;data-centre-locations&#34;&gt;Data Centre Locations
&lt;/h3&gt;&lt;p&gt;Each provider has different data centre locations that could impact your choice based on the proximity to your target audience. Scaleway is only in Europe, Civo is on both sides of the pond, Server Space is in seven countries worldwide, and Upcloud has multiple regions in several countries, providing flexibility for diverse deployment needs.&lt;/p&gt;
&lt;h3 id=&#34;readwritemany-support&#34;&gt;ReadWriteMany Support
&lt;/h3&gt;&lt;p&gt;ReadWriteMany (RWX) is a crucial feature for Kubernetes clusters that allows multiple pods to read from and write to the same persistent volume simultaneously. This capability is particularly important for workloads requiring shared access, such as content management systems, logging, and certain types of databases.&lt;/p&gt;
&lt;p&gt;Currently, the major cloud providers (hyperscalers like AWS, Google Cloud, and Azure) are the only ones that support RWX natively in their managed Kubernetes offerings. As such, the managed Kubernetes providers we discuss here do not yet offer built-in RWX support. When asked about this limitation, they indicated that support for this is on their roadmaps, but it is at least six months away.&lt;/p&gt;
&lt;p&gt;However, this isn&amp;rsquo;t a deal breaker.  For those who require RWX functionality today, there are several workaround options you can explore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Install Longhorn&lt;/strong&gt;: The easiest option for setting up block storage in your cluster. It provides a simple way to add RWX support to your pods.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rook or OpenEBS&lt;/strong&gt;: These alternatives are more flexible and powerful, allowing you to build a highly customized storage solution for your cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using these self-managed storage solutions can also lead to cost savings. They utilize the unused storage already available on your nodes, avoiding the need to purchase additional storage volumes from the cloud provider. This cost-effective approach means that as long as your node storage is sufficient, you won&amp;rsquo;t incur extra charges.&lt;/p&gt;
&lt;h3 id=&#34;official-terraform-support&#34;&gt;Official Terraform Support
&lt;/h3&gt;&lt;p&gt;Official Terraform support is vital for those looking to adopt infrastructure-as-code practices. While Scaleway, Upcloud, and Civo offer full Terraform integration, Server Space’s support is currently incomplete, potentially complicating automated deployments.&lt;/p&gt;
&lt;h3 id=&#34;cluster-provisioning-speed&#34;&gt;Cluster provisioning speed
&lt;/h3&gt;&lt;p&gt;Another technical feature to consider is the cluster provisioning speed, although this is less of an issue in production.  During development, however, you&amp;rsquo;re going to be spinning up and tearing down your clusters quite often.  It&amp;rsquo;s important to factor in how much time your developers are spending waiting on these operations.&lt;/p&gt;
&lt;p&gt;Civo is very fast: They claim one and a half minutes, and while it sometimes goes over, it&amp;rsquo;s always less than two.  This is still the fastest I&amp;rsquo;ve seen anywhere.  Scaleway is quite slow, relatively.  I haven&amp;rsquo;t had a chance to test this on Upcloud or Server Space yet so if anyone out there has data on this, please share it with me, and I&amp;rsquo;ll update this article.&lt;/p&gt;
&lt;p&gt;To see how these compare with other providers, take a look at the article &lt;a class=&#34;link&#34; href=&#34;https://medium.com/@elliotgraebert/comparing-the-top-eight-managed-kubernetes-providers-2ae39662391b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Comparing the Top Eight Managed Kubernetes Providers&lt;/a&gt;.  It also has some great analysis.  The only problem with that article is that it doesn&amp;rsquo;t review  outside of the top eight.  Scaleway is included, which is nice.&lt;/p&gt;
&lt;h3 id=&#34;years-in-business&#34;&gt;Years in Business
&lt;/h3&gt;&lt;p&gt;The experience of each provider varies significantly, which can influence the maturity and reliability of their services. Scaleway, established 25 years ago, has a long-standing presence in the European cloud market, offering a range of services beyond Kubernetes. Upcloud, with 12 years in operation, also brings a well-established infrastructure and a solid reputation for reliability. Civo, though relatively newer with 6 years in business, has quickly made a name for itself as a specialized Kubernetes provider, particularly valued by developers for its simplicity and speed. Server Space, the newest provider on this list with 5 years in business, offers a streamlined approach with competitive pricing and growing popularity in the European market.&lt;/p&gt;
&lt;h3 id=&#34;service-level-agreements-slas&#34;&gt;Service Level Agreements (SLAs)
&lt;/h3&gt;&lt;p&gt;The SLAs offered by each provider reflect their commitment to uptime and service reliability, which are essential considerations for production workloads. Upcloud leads with a 100% SLA, providing the highest guarantee of availability among the providers reviewed. Civo, with a 99.95% SLA, balances reliability with cost-efficiency, making it suitable for various production applications. Scaleway’s 99.5% SLA may appeal to users prioritizing budget-conscious solutions with some tolerance for minor downtime. Server Space, with a 99.9% SLA, offers solid reliability while remaining competitively priced. These SLAs give users a range of options to match their reliability needs and budget.&lt;/p&gt;
&lt;h3 id=&#34;headquarters&#34;&gt;Headquarters
&lt;/h3&gt;&lt;p&gt;Each provider’s headquarters location offers insight into their operational focus and areas of influence. Scaleway is headquartered in Paris, France, and emphasizes data sovereignty and compliance with European regulations, which can be beneficial for EU-based companies. Upcloud, based in Helsinki, Finland, operates with a global outlook, providing services across many regions and maintaining a strong presence in Europe. Civo, headquartered in London, UK, has a focus on simplicity and developer-centric solutions, particularly attractive to startups and small to medium-sized enterprises. Server Space, based in Amsterdam, Netherlands, also emphasizes European data regulations and affordability, appealing to businesses across the EU and beyond.&lt;/p&gt;
&lt;p&gt;One notable aspect of the providers compared here is that none of them are headquartered in the United States. This offers a potential advantage in terms of data privacy, as they are not directly subject to US laws that can sometimes compel US-based companies to turn over data stored in other countries.&lt;/p&gt;
&lt;p&gt;A prominent case exemplifying this challenge is the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Microsoft_Corp._v._United_States&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Microsoft Corp. v. United States case&lt;/a&gt;. In 2013, the U.S. Department of Justice sought to access emails stored in Microsoft’s Ireland data center as part of a criminal investigation. Microsoft argued that the US warrant should not apply extraterritorially to data stored outside the US. Ultimately, the US Court of Appeals ruled in favor of Microsoft, setting a precedent that US-issued warrants do not reach overseas data centers by default. In 2018, however, the passage of the CLOUD Act (Clarifying Lawful Overseas Use of Data Act) revised US policy, allowing authorities to access foreign-stored data held by US-based companies through new, standardized agreements between nations.&lt;/p&gt;
&lt;p&gt;This shift in legislation means that US-based companies may still face complex requirements when holding data abroad. For businesses concerned about extraterritorial data demands, providers headquartered outside the U.S., such as Scaleway in France, Upcloud in Finland, Civo in the UK, and Server Space in the Netherlands, might offer additional peace of mind regarding international data sovereignty.&lt;/p&gt;
&lt;h2 id=&#34;cost-breakdown&#34;&gt;Cost Breakdown
&lt;/h2&gt;&lt;p&gt;Here’s a breakdown of the basic cost for running a production-ready cluster with each provider, including managed Kubernetes, nodes, and a load balancer.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Product&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Scaleway&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Upcloud&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Civo&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;Server Space&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Managed Kubernetes&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;€80&lt;/td&gt;
          &lt;td&gt;€60&lt;/td&gt;
          &lt;td&gt;$0.00&lt;/td&gt;
          &lt;td&gt;€38&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;4 vCPU 8 GB Nodes (x3)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;€77 * 3 = €231&lt;/td&gt;
          &lt;td&gt;€52 * 3 = €156&lt;/td&gt;
          &lt;td&gt;$40 * 3 = $120&lt;/td&gt;
          &lt;td&gt;€91.69&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Load Balancer&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;€11.52&lt;/td&gt;
          &lt;td&gt;€30&lt;/td&gt;
          &lt;td&gt;$10.00&lt;/td&gt;
          &lt;td&gt;€0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;€322.52&lt;/td&gt;
          &lt;td&gt;€246&lt;/td&gt;
          &lt;td&gt;$130.00&lt;/td&gt;
          &lt;td&gt;€129.69&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Converted to USD&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;$357.94&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;$273.02&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;$130.00&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;$144.00&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The above cost comparison does not include additional services like block storage, object storage, or database services. I&amp;rsquo;m focusing on the essential resources needed.&lt;/p&gt;
&lt;h3 id=&#34;cost-analysis&#34;&gt;Cost Analysis
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scaleway&lt;/strong&gt;: The most expensive option at $357.94/month, primarily due to higher managed Kubernetes and node costs. It may still be worth it for those needing extensive data center options and a strong European presence.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upcloud&lt;/strong&gt;: A mid-tier option at $273.02/month, offering a competitive SLA and global data center coverage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Civo&lt;/strong&gt;: The most affordable choice at $130.00/month. Its free managed Kubernetes service significantly lowers the barrier to entry, making it suitable for startups or small-scale production environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Space&lt;/strong&gt;: Priced at $144.00/month, it offers a balanced approach with competitive node pricing and a relatively low basic cluster cost. However, incomplete Terraform support might be a consideration.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;additional-considerations&#34;&gt;Additional Considerations
&lt;/h2&gt;&lt;p&gt;While the above costs cover the basic managed Kubernetes setup, additional services like Block storage, Object storage, and Database services could further influence the overall expenses. Moreover, the lack of ReadWriteMany support across all providers could be a factor in workload planning.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;For those looking to avoid the restrictive egress fees of major hyperscalers, these four providers offer a solid alternative. Civo emerges as the most affordable option, while Scaleway offers more features and data center options at a higher cost. Upcloud and Server Space fall somewhere in between, with unique strengths that might appeal to different use cases.&lt;/p&gt;
&lt;p&gt;When choosing the right provider, consider factors like data centre location, pricing, SLA, and Terraform support in relation to your specific needs. Each provider has its own strengths, and this comparison aims to help you find the most cost-effective and reliable Kubernetes environment for your workloads.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Load Balancing SSH or Other TCP Connections? Preserve Client IP Addresses with One of These Tools</title>
        <link>https://colan.pro/blog/load-balancing-ssh-or-other-tcp-connections/</link>
        <pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/load-balancing-ssh-or-other-tcp-connections/</guid>
        <description>&lt;img src="https://colan.pro/blog/load-balancing-ssh-or-other-tcp-connections/DALL_E_2024-09-06_23.33.03_-_A_wide_banner_image_representing_a_network_infrastructure_with_servers__load_balancers__and_SSH_connections._The_image_should_feature_traffic_flow_vis.webp" alt="Featured image of post Load Balancing SSH or Other TCP Connections? Preserve Client IP Addresses with One of These Tools" /&gt;&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;In modern cloud environments, applications often sit behind load balancers or proxies to manage incoming traffic efficiently. While this setup helps distribute connections and scale services, it introduces a challenge: the original client’s IP address gets replaced by the proxy’s IP address. For many applications—particularly those using &lt;strong&gt;SSH&lt;/strong&gt;—this can be problematic, as it obscures the real source of a connection.&lt;/p&gt;
&lt;p&gt;Unlike &lt;strong&gt;HTTP&lt;/strong&gt; traffic, which already has mechanisms like the &lt;code&gt;X-Forwarded-For&lt;/code&gt; header to pass the client’s IP address to the backend, &lt;strong&gt;SSH&lt;/strong&gt; and other TCP-based services don’t have built-in support for this. This makes it difficult for backend services to log or restrict access based on the original client IP address, which is important for security and monitoring.&lt;/p&gt;
&lt;p&gt;To solve this, tools like &lt;a class=&#34;link&#34; href=&#34;https://github.com/path-network/go-mmproxy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://github.com/cloudflare/mmproxy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;mmproxy&lt;/strong&gt;&lt;/a&gt;, and &lt;a class=&#34;link&#34; href=&#34;https://www.kernel.org/doc/html/latest/networking/tproxy.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;TPROXY&lt;/strong&gt;&lt;/a&gt; exist to preserve the client’s IP address while forwarding traffic through a proxy. Each tool has unique strengths and is suitable for different environments. In this article, we’ll break down the differences between these solutions and help you choose the right one for handling SSH connections behind a proxy.&lt;/p&gt;
&lt;h2 id=&#34;why-preserving-client-ip-addresses-matters&#34;&gt;Why Preserving Client IP Addresses Matters
&lt;/h2&gt;&lt;p&gt;When using SSH or similar services to manage servers, it’s common to apply security rules based on the client’s IP address. For example, you might want to allow access only from a specific range of trusted IP addresses or monitor connections based on where they originate. However, when an SSH server sits behind a load balancer or proxy, the server will see the proxy’s IP address instead of the client’s IP address.&lt;/p&gt;
&lt;p&gt;This loss of visibility into the real source IP address can create security blind spots. Fortunately, the &lt;strong&gt;PROXY protocol&lt;/strong&gt; solves this issue by passing connection details, like the original client’s IP address, to the backend service. However, many services, including &lt;strong&gt;SSHD&lt;/strong&gt; (the SSH daemon), don’t natively support the PROXY protocol. That’s where &lt;strong&gt;go-mmproxy&lt;/strong&gt;, &lt;strong&gt;mmproxy&lt;/strong&gt;, and &lt;strong&gt;TPROXY&lt;/strong&gt; come into play.&lt;/p&gt;
&lt;p&gt;Before diving into the comparison, it&amp;rsquo;s important to understand how these tools function at a high level.  You can use one of them as &lt;em&gt;another&lt;/em&gt; proxy that sits betweeen your load balancer and your service.  They capture the connection, spoof the original client’s IP address, and then forward the remaining payload to the destination service. This ensures that your backend service can still see and act upon the original client’s IP address while handling the connection.&lt;/p&gt;
&lt;p&gt;The request flow looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Client request &amp;gt; Load balancer &amp;gt; &lt;strong&gt;go-mmproxy/mmproxy/TPROXY&lt;/strong&gt; &amp;gt; Your service (e.g. SSH)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;comparing-the-tools-go-mmproxy-vs-mmproxy-vs-tproxy&#34;&gt;Comparing the Tools: go-mmproxy vs mmproxy vs TPROXY
&lt;/h2&gt;&lt;p&gt;So how do you decide which one to use? Each tool has its own strengths, weaknesses, and ideal use cases. Choosing the right one depends on factors like performance, ease of setup, resource efficiency, and the complexity of your environment. Below is a comparison table that breaks down the key features and considerations for each tool, helping you make an informed decision based on your specific needs for handling these types of connections.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Feature/Aspect&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;mmproxy&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Go&lt;/td&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;Kernel-level feature (uses iptables)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Slightly higher overhead due to Go’s runtime&lt;/td&gt;
          &lt;td&gt;Lower overhead (written in C)&lt;/td&gt;
          &lt;td&gt;High performance, minimal overhead (kernel)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Ease of Use&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Easy to set up, Go binaries are simple to compile or download&lt;/td&gt;
          &lt;td&gt;Requires compilation or binaries&lt;/td&gt;
          &lt;td&gt;More complex to configure (requires iptables and kernel support)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Simple CLI options with flags like &lt;code&gt;--allowed-subnets&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Simple CLI, but requires C and networking knowledge&lt;/td&gt;
          &lt;td&gt;Complex &lt;code&gt;iptables&lt;/code&gt; rules and kernel setup&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Routing&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Requires Linux routing (ip rules and iptables)&lt;/td&gt;
          &lt;td&gt;Also requires routing setup&lt;/td&gt;
          &lt;td&gt;Handles routing natively within the kernel&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;IPv4/IPv6 Support&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Full support for IPv4 and IPv6 traffic&lt;/td&gt;
          &lt;td&gt;Full support for IPv4 and IPv6&lt;/td&gt;
          &lt;td&gt;Full support for IPv4 and IPv6&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Scales well with Go’s concurrency, but with a slightly higher memory footprint&lt;/td&gt;
          &lt;td&gt;Lightweight and highly scalable&lt;/td&gt;
          &lt;td&gt;Extremely scalable, as it’s part of the kernel&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Resource Efficiency&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Higher CPU and memory usage due to Go runtime&lt;/td&gt;
          &lt;td&gt;Extremely lightweight (C-based)&lt;/td&gt;
          &lt;td&gt;Extremely efficient (minimal CPU and memory usage)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Concurrency&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Built-in concurrency via Go goroutines&lt;/td&gt;
          &lt;td&gt;Relies on system-level processes/threads&lt;/td&gt;
          &lt;td&gt;Kernel-level concurrency, highly optimized&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Easy with &lt;code&gt;go get&lt;/code&gt; or precompiled binaries&lt;/td&gt;
          &lt;td&gt;Requires manual compilation or prebuilt binaries&lt;/td&gt;
          &lt;td&gt;Built into the Linux kernel (but requires iptables setup)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Use Case Fit&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Ideal for those looking for ease of use with Go&lt;/td&gt;
          &lt;td&gt;Best for lightweight, low-resource environments&lt;/td&gt;
          &lt;td&gt;Ideal for complex, large-scale deployments with advanced networking needs&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;detailed-breakdown&#34;&gt;Detailed Breakdown
&lt;/h2&gt;&lt;h3 id=&#34;language-and-resource-efficiency&#34;&gt;Language and Resource Efficiency
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;: Written in &lt;strong&gt;Go&lt;/strong&gt;, it benefits from Go’s built-in concurrency model (goroutines), which makes handling many simultaneous SSH connections efficient. However, Go’s garbage collector introduces slightly more memory overhead compared to &lt;strong&gt;mmproxy&lt;/strong&gt; or &lt;strong&gt;TPROXY&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mmproxy&lt;/strong&gt;: Written in &lt;strong&gt;C&lt;/strong&gt;, &lt;strong&gt;mmproxy&lt;/strong&gt; is extremely lightweight and resource-efficient. Its minimal CPU and memory usage make it ideal for servers where resource efficiency is critical.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;: As a kernel-level feature, &lt;strong&gt;TPROXY&lt;/strong&gt; is the most resource-efficient of the three. Because it operates entirely within the Linux kernel, it avoids the overhead of user-space processes, making it perfect for environments where performance and scalability are essential.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;performance&#34;&gt;Performance
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;: Go’s runtime adds some overhead due to garbage collection and memory management. While this doesn’t impact moderate-traffic environments significantly, it may become a factor in large-scale, high-performance setups.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mmproxy&lt;/strong&gt;: &lt;strong&gt;mmproxy&lt;/strong&gt;’s C-based implementation ensures minimal overhead, making it more suitable for environments with high traffic and performance requirements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;: As a kernel-native solution, &lt;strong&gt;TPROXY&lt;/strong&gt; is the most performant, with almost no overhead. It can handle large volumes of traffic with minimal CPU and memory usage, making it ideal for high-performance and low-latency SSH traffic scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ease-of-use-and-setup&#34;&gt;Ease of Use and Setup
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;: Installation is straightforward, especially if you are familiar with Go. You can either compile it using &lt;code&gt;go get&lt;/code&gt; or download a precompiled binary. The configuration is user-friendly, with intuitive CLI options like &lt;code&gt;--allowed-subnets&lt;/code&gt; to filter incoming connections by IP address.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mmproxy&lt;/strong&gt;: Setting up &lt;strong&gt;mmproxy&lt;/strong&gt; can be slightly more involved, particularly if you need to compile it from source. Precompiled binaries are available, but you need to be comfortable working with C-based tools and networking configurations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;: Setting up &lt;strong&gt;TPROXY&lt;/strong&gt; is more complex, as it requires configuring &lt;code&gt;iptables&lt;/code&gt; rules and custom routing tables in the Linux kernel. While this offers maximum flexibility, it demands more networking expertise and time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configuration-and-features&#34;&gt;Configuration and Features
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;: Offers a wide range of configuration options, including the ability to restrict access to specific IP address ranges using the &lt;code&gt;--allowed-subnets&lt;/code&gt; flag. Its features are well-suited for users who need flexibility in filtering and managing connections.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mmproxy&lt;/strong&gt;: &lt;strong&gt;mmproxy&lt;/strong&gt; provides basic functionality to preserve client IP addresses and forward traffic, without the additional filtering features found in &lt;strong&gt;go-mmproxy&lt;/strong&gt;. It’s designed to be simple, lightweight, and efficient.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;: &lt;strong&gt;TPROXY&lt;/strong&gt; allows for advanced configuration at the kernel level. You can create complex routing and traffic management rules using &lt;code&gt;iptables&lt;/code&gt;, making it highly flexible but also more difficult to set up and maintain.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;routing-setup&#34;&gt;Routing Setup
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt; and &lt;strong&gt;mmproxy&lt;/strong&gt;: Both require additional routing setup using &lt;code&gt;iptables&lt;/code&gt; and custom routing tables to forward traffic while preserving the original client IP address. This setup involves creating rules to mark packets and routing them correctly to the backend SSH service.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;: &lt;strong&gt;TPROXY&lt;/strong&gt; natively handles routing within the kernel, eliminating the need for external routing tools. However, the initial setup with &lt;code&gt;iptables&lt;/code&gt; can be complex and requires an in-depth understanding of networking.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;scalability-and-concurrency&#34;&gt;Scalability and Concurrency
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go-mmproxy&lt;/strong&gt;: Thanks to Go’s concurrency model, &lt;strong&gt;go-mmproxy&lt;/strong&gt; scales well in environments that need to handle many SSH connections at once. However, its Go runtime introduces some resource overhead, which can limit scalability in extremely resource-constrained environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mmproxy&lt;/strong&gt;: &lt;strong&gt;mmproxy&lt;/strong&gt; scales well due to its lightweight, low-overhead design. It relies on system-level concurrency, which can be fine-tuned for the specific environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TPROXY&lt;/strong&gt;: As part of the Linux kernel, &lt;strong&gt;TPROXY&lt;/strong&gt; scales effortlessly, handling large volumes of traffic with minimal overhead. It is the best choice for large-scale, performance-critical deployments where resource efficiency is paramount.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;recommendations&#34;&gt;Recommendations
&lt;/h2&gt;&lt;h3 id=&#34;use-go-mmproxy-if&#34;&gt;Use go-mmproxy if&amp;hellip;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;You want a simple, easy-to-use solution for preserving client IP addresses in SSH traffic.&lt;/li&gt;
&lt;li&gt;You are familiar with Go or prefer using precompiled binaries.&lt;/li&gt;
&lt;li&gt;You need features like IP address filtering (&lt;code&gt;--allowed-subnets&lt;/code&gt;) for extra security.&lt;/li&gt;
&lt;li&gt;Your environment handles moderate traffic and can tolerate the Go runtime’s resource usage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;use-mmproxy-if&#34;&gt;Use mmproxy if&amp;hellip;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;You need a highly efficient and lightweight solution for handling SSH traffic.&lt;/li&gt;
&lt;li&gt;Resource constraints are a priority, and you want to minimize CPU and memory usage.&lt;/li&gt;
&lt;li&gt;You’re comfortable with C-based tools and networking configurations.&lt;/li&gt;
&lt;li&gt;You prefer a minimalistic approach and don’t require advanced filtering features.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;use-tproxy-if&#34;&gt;Use TPROXY if&amp;hellip;
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;You need the highest possible performance and scalability with minimal resource overhead.&lt;/li&gt;
&lt;li&gt;You’re working in a large-scale environment with complex networking requirements.&lt;/li&gt;
&lt;li&gt;You have the expertise to configure &lt;code&gt;iptables&lt;/code&gt; and manage routing tables in the Linux kernel.&lt;/li&gt;
&lt;li&gt;You want full control over how traffic is handled at the network level, with the ability to create custom rules and manage routing efficiently.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;When it comes to preserving client IP addresses for TCP connections behind proxies, the choice between &lt;strong&gt;go-mmproxy&lt;/strong&gt;, &lt;strong&gt;mmproxy&lt;/strong&gt;, and &lt;strong&gt;TPROXY&lt;/strong&gt; depends on your specific needs and environment. &lt;strong&gt;go-mmproxy&lt;/strong&gt; offers ease of use and flexibility, while &lt;strong&gt;mmproxy&lt;/strong&gt; is a highly efficient, resource-light option for more constrained setups. &lt;strong&gt;TPROXY&lt;/strong&gt; provides unmatched performance and scalability but requires advanced configuration.&lt;/p&gt;
&lt;p&gt;By understanding the strengths of each tool, you can choose the right solution for your traffic needs and ensure your systems maintain the security and visibility needed to manage connections effectively.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Having Trouble Logging into Sites Protected with Cloudflare?</title>
        <link>https://colan.pro/blog/having-trouble-logging-into-sites-protected-with-cloudflare/</link>
        <pubDate>Tue, 02 Jul 2024 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/having-trouble-logging-into-sites-protected-with-cloudflare/</guid>
        <description>&lt;img src="https://colan.pro/blog/having-trouble-logging-into-sites-protected-with-cloudflare/DALL%C2%B7E%202024-07-02%2020.56.07%20-%20A%20user%20trying%20to%20log%20into%20a%20website%20protected%20by%20Cloudflare%27s%20Turnstile,%20showing%20frustration%20with%20failed%20verifications%20on%20multiple%20devices.%20The%20image%20.webp" alt="Featured image of post Having Trouble Logging into Sites Protected with Cloudflare?" /&gt;&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Recently, I&amp;rsquo;ve encountered a recurring problem while trying to log into several sites that use &lt;a class=&#34;link&#34; href=&#34;https://www.cloudflare.com/products/turnstile/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cloudflare&amp;rsquo;s Turnstile&lt;/a&gt; for bot protection as a replacement for &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/CAPTCHA&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CAPTCHAs&lt;/a&gt;.  It&amp;rsquo;s a machine-learning tool they&amp;rsquo;ve developed instead.  Personally, I&amp;rsquo;ve seen this on major sites like GitLab.com, ChatGPT, and even Cloudflare itself. While Turnstile aims to enhance security, it often produces false positives that can be rather frustrating.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not just me experiencing these issues. I&amp;rsquo;ve seen other users complain about this in various forums, sharing workarounds that sometimes work for some but not for others. There doesn&amp;rsquo;t seem to be a universal solution that works for everyone.&lt;/p&gt;
&lt;p&gt;The inconsistency of Turnstile is another significant issue. Despite having the same Firefox configuration on both my office desktop and my mobile laptop, which are synchronized via my Firefox account, I can log into GitLab.com on one but not the other. What does Turnstile think is different about them? I&amp;rsquo;m really not sure.&lt;/p&gt;
&lt;h2 id=&#34;potential-solutions&#34;&gt;Potential Solutions
&lt;/h2&gt;&lt;h3 id=&#34;improve-turnstile-accuracy&#34;&gt;Improve Turnstile Accuracy
&lt;/h3&gt;&lt;p&gt;Cloudflare needs to continually refine its algorithms to reduce the number of false positives. This involves better distinguishing between legitimate users and bots through more advanced machine learning techniques.&lt;/p&gt;
&lt;h3 id=&#34;broader-browser-support&#34;&gt;Broader Browser Support
&lt;/h3&gt;&lt;p&gt;Ensuring that Turnstile operates smoothly across all major browsers and devices is crucial. Regular testing and updates can help achieve this goal.  Most of the time, Firefox doesn&amp;rsquo;t work for me, but does in Chromium-based browsers (e.g. Chrome).  Other users are reporting the opposite:  Firefox works, but Chromium/Chrome doesn&amp;rsquo;t.&lt;/p&gt;
&lt;h3 id=&#34;user-feedback-mechanism&#34;&gt;User Feedback Mechanism
&lt;/h3&gt;&lt;p&gt;Implementing a more efficient feedback mechanism where users can report issues directly can help Cloudflare identify and address specific problems more quickly. This feedback loop is essential for continuous improvement.&lt;/p&gt;
&lt;p&gt;Adding a button for &amp;ldquo;Hey, I&amp;rsquo;m a human!&amp;rdquo; would be nice, but there would have to be a way to prevent bots from using it too.  Maybe add some easy out-of-band task that only humans can do?&lt;/p&gt;
&lt;h3 id=&#34;streamlined-ux-design&#34;&gt;Streamlined UX Design
&lt;/h3&gt;&lt;p&gt;Simplifying the verification process can help maintain a positive user experience.  What if you only had to do this infrequently?  And only once for all of the sites you log into?  If I get through, how about issuing me a token (e.g. a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/WebAuthn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;passkey&lt;/a&gt;) that works for an entire year everywhere?  This brings up authentication on the Web generally, but maybe we need to bring these two discussions together.&lt;/p&gt;
&lt;h3 id=&#34;transparency&#34;&gt;Transparency
&lt;/h3&gt;&lt;p&gt;Let us know why we&amp;rsquo;re being blocked, and what we can do to fix it.  Keeping this secret so the bots don&amp;rsquo;t adapt isn&amp;rsquo;t helpful here.  And we all know that &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Security_through_obscurity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;security through obscurity&lt;/a&gt; doesn&amp;rsquo;t work anyway.&lt;/p&gt;
&lt;h2 id=&#34;workarounds&#34;&gt;Workarounds
&lt;/h2&gt;&lt;p&gt;What eventually worked for me on most of the sites I use is a recipe from &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/gitlab-org/gitlab/-/issues/421396#note_1979222140&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the GitLab.com issue&lt;/a&gt;, thanks to &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/malix_off&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Alix Brunet&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Shut down your browser by quitting it.
&lt;ul&gt;
&lt;li&gt;Make sure every instance has been exited, and no background processes are remaining.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Launch your browser on the command line with all extensions/plugins disabled.
&lt;ul&gt;
&lt;li&gt;On Firefox, this is &lt;code&gt;firefox --safe-mode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On Chromium-based browsers, this is with the &lt;code&gt;--disable-extensions&lt;/code&gt; switch, e.g. &lt;code&gt;flatpak run org.chromium.Chromium --disable-extensions&lt;/code&gt; if you&amp;rsquo;re using the Flatpak package.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Log in to the site you&amp;rsquo;re trying to log into.
&lt;ul&gt;
&lt;li&gt;It should work this time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Shut down your broswser again.
&lt;ul&gt;
&lt;li&gt;Make sure every instance has been exited, and no background processes are remaining.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Start your browser normally, without disabling extensions.
&lt;ul&gt;
&lt;li&gt;This should now work, assuming that you don&amp;rsquo;t clear your cookies automatically on exit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, for ChatGPT, I also had to disable my VPN.  The above process didn&amp;rsquo;t work until I did that.  My login cookies weren&amp;rsquo;t helping on their own; I kept getting the Turnstile checkbox.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Security is good, but if it doesn&amp;rsquo;t allow authorized parties access, what&amp;rsquo;s the point of the service?  As an extreme example, blocking everything is great security, but users will go elsewhere.&lt;/p&gt;
&lt;p&gt;Maybe this is a good example of machine learning that isn&amp;rsquo;t quite ready to leave the lab just yet.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>The Hidden Costs of Cloud Egress Fees: Finding a Better Alternative</title>
        <link>https://colan.pro/blog/hidden-costs-of-cloud-egress-fees/</link>
        <pubDate>Tue, 25 Jun 2024 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/hidden-costs-of-cloud-egress-fees/</guid>
        <description>&lt;img src="https://colan.pro/blog/hidden-costs-of-cloud-egress-fees/DALL%C2%B7E%202024-06-25%2008.30.58%20-%20A%20wide%20banner%20image%20illustrating%20the%20concept%20of%20egress%20fees%20in%20cloud%20computing.%20The%20image%20should%20show%20a%20cloud%20with%20data%20flowing%20out%20through%20a%20narrow,%20.webp" alt="Featured image of post The Hidden Costs of Cloud Egress Fees: Finding a Better Alternative" /&gt;&lt;h2 id=&#34;using-third-party-services-with-the-major-cloud-providers&#34;&gt;Using third-party services with the major cloud providers
&lt;/h2&gt;&lt;p&gt;Looking for a cloud provider that will maintain the low-cost advantage of working with third-party services?  They don&amp;rsquo;t advertise this, but the major Infrastructure-as-a-service (IaaS) providers charge you exorbitantly to get data out of their networks.  Why?  You can use them as long as you want, but you can never leave.  It&amp;rsquo;s been referred to as the &amp;ldquo;Hotel California effect&amp;rdquo;, and these are called &amp;ldquo;egress fees&amp;rdquo;.  By the time you realize how much you&amp;rsquo;re paying for cloud computing at Amazon Web Services (AWS), Microsoft&amp;rsquo;s Azure, or Google Cloud Platform (GCP), you have all of your data there, and you&amp;rsquo;re not going to pay the ransom (so you just stick around).&lt;/p&gt;
&lt;p&gt;I currently have a need to send data to Wasabi, an independent storage provider, but can&amp;rsquo;t justify the cost of getting my data over there from the Big 3.  Exporting the data alone would cost more than storing my data.  So I need a better option.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to mix &amp;amp; match services from various providers, it&amp;rsquo;s not worth it, because the money you&amp;rsquo;d be saving by going elsewhere for specialized services is lost on egress fees.  It&amp;rsquo;s anti-competitive, and governments are starting to catch on.  And while this has been talked about before, it&amp;rsquo;s not widely recognized as as problem.&lt;/p&gt;
&lt;h2 id=&#34;enter-the-bandwidth-alliance&#34;&gt;Enter the Bandwidth Alliance
&lt;/h2&gt;&lt;p&gt;One of the big players, Cloudflare, has been working on this issue through its &lt;a class=&#34;link&#34; href=&#34;https://www.cloudflare.com/en-ca/bandwidth-alliance/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bandwidth Alliance&lt;/a&gt; (see original &lt;a class=&#34;link&#34; href=&#34;https://blog.cloudflare.com/bandwidth-alliance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;announcement&lt;/a&gt;).  It&amp;rsquo;s a good initiative, but let&amp;rsquo;s see how much traction it has over time.  It looks like the number of members has doubled in 6 years, but some of agreements are simply deals between Cloudflare and the other party, not across the entire alliance.  And I haven&amp;rsquo;t seen more commitments from the companies to drop these fees entirely.  Yes, some of them &lt;em&gt;never&lt;/em&gt; charged these fees, which is great, but it would be really nice if ones that did stopped doing so.&lt;/p&gt;
&lt;h2 id=&#34;so-what-do-we-do&#34;&gt;So what do we do?
&lt;/h2&gt;&lt;p&gt;Due diligence: Do your research on a cloud provider before you sign up with them initially.  What do they charge?  Don&amp;rsquo;t just look at services you want there; look at how much it&amp;rsquo;s going to cost you to get your data somewhere else.  If they don&amp;rsquo;t list &amp;ldquo;egress&amp;rdquo; fees, look for &amp;ldquo;network&amp;rdquo; or &amp;ldquo;transfer out&amp;rdquo; fees.  If they don&amp;rsquo;t provide it, ask. Don&amp;rsquo;t sign up for a cloud provider in the first place if you&amp;rsquo;re not happy with those terms.&lt;/p&gt;
&lt;p&gt;If you do get stuck in one, and want to get out, you&amp;rsquo;d better hope it&amp;rsquo;s Google Cloud Platform (GCP).  They&amp;rsquo;re the only one that &lt;a class=&#34;link&#34; href=&#34;https://cloud.google.com/blog/products/networking/eliminating-data-transfer-fees-when-migrating-off-google-cloud&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;allows you to get out, albeit permanently&lt;/a&gt;.  For a good analysis of the offering, check out the &lt;a class=&#34;link&#34; href=&#34;https://www.theregister.com/2024/01/11/google_cloud_egress_fees/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Register article&lt;/a&gt;.  At least it&amp;rsquo;s something.&lt;/p&gt;
&lt;p&gt;Holori has done &lt;a class=&#34;link&#34; href=&#34;https://medium.com/@alexandre_43174/the-surprising-truth-about-cloud-egress-costs-d1be3f70d001&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a comparison of these costs&lt;/a&gt;, and provides a &lt;a class=&#34;link&#34; href=&#34;https://holori.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;tool&lt;/a&gt; for spend across clouds.  They don&amp;rsquo;t support an exhaustive list of providers, but hopefully they&amp;rsquo;re working on this.&lt;/p&gt;
&lt;p&gt;I looked into &lt;a class=&#34;link&#34; href=&#34;https://fly.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Fly.io&lt;/a&gt; because they run &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Containerization_%28computing%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;containers&lt;/a&gt; wherever you want, thinking that they&amp;rsquo;d support this kind of activity.  They focus internationally, right?  So you&amp;rsquo;d think they&amp;rsquo;d support &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Data_portability&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;data portability&lt;/a&gt; between cloud providers.  Well, guess again: &amp;ldquo;&lt;a class=&#34;link&#34; href=&#34;https://fly.io/docs/about/pricing/#outbound-data-transfer&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;We bill for outbound data transfer from the region a VM is running in, inbound transfer is free.&lt;/a&gt;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Of course there&amp;rsquo;s Cloudflare; they&amp;rsquo;re the ones pushing on this the hardest.  They have a &amp;ldquo;serverless&amp;rdquo; computing offering called &lt;a class=&#34;link&#34; href=&#34;https://developers.cloudflare.com/workers/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Workers&lt;/a&gt;.  (I&amp;rsquo;m putting &amp;ldquo;serverless&amp;rdquo; in quotation marks because it&amp;rsquo;s a silly name.  It should really be called &amp;ldquo;server-managed&amp;rdquo; because there are still servers; you just don&amp;rsquo;t have to manage them yourself.)  I looked into this option, but I need something that&amp;rsquo;ll respond to possibly long-running SSH connections, and they don&amp;rsquo;t seem to be designed for that.  What I could really use is a similar offering that works with containers, not just code (sorry, but I&amp;rsquo;m not rewriting SSHD in JavaScript) that can respond to SSH requests.  It&amp;rsquo;s either that or Kubernetes.  And while they support &lt;a class=&#34;link&#34; href=&#34;https://www.cloudflare.com/integrations/kubernetes/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;services around Kubernetes&lt;/a&gt;, they don&amp;rsquo;t offer it themselves.  (Cloudflare:  If you&amp;rsquo;re reading this, please add support for server-managed containers and Kubernetes!)&lt;/p&gt;
&lt;p&gt;My last hope was one of the &lt;a class=&#34;link&#34; href=&#34;https://www.openstack.org/marketplace/public-clouds/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenStack providers&lt;/a&gt;.  If they&amp;rsquo;re into &lt;a class=&#34;link&#34; href=&#34;https://openinfra.dev/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;open infrastructure&lt;/a&gt;, &lt;em&gt;they&amp;rsquo;d&lt;/em&gt; certainly be into data portability.  No dice.  My favourite Canadian OpenStack provider, &lt;a class=&#34;link&#34; href=&#34;https://vexxhost.com/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vexxhost&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://vexxhost.com/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;charges $0.10/GB (or $100/TB)&lt;/a&gt;.  I looked into the other ones as well, but none of them advertised this feature so I just assumed it wasn&amp;rsquo;t available.  If I were them, I&amp;rsquo;d be promoting it as a selling point.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;In the end, I landed on &lt;a class=&#34;link&#34; href=&#34;https://www.scaleway.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Scaleway&lt;/a&gt; for the project I&amp;rsquo;m currenlty working on.  They&amp;rsquo;ve never charged for this, and actually promote it in &lt;a class=&#34;link&#34; href=&#34;https://www.scaleway.com/en/blog/webcastor-migration-interview/#did-you-have-to-pay-your-former-cloud-provider-egress-fees&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;their marketing&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scaleway believes in unmetered bandwidth and is committed to working with the Bandwidth Alliance on advocating for all-unmetered plans on customer connections (&lt;a class=&#34;link&#34; href=&#34;https://www.cloudflare.com/en-ca/partners/technology-partners/scaleway/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Source&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They&amp;rsquo;re a good choice in this case because they support the Bandwidth Alliance, offer server-managed containers and Kubernetes (even an option that works with other cloud providers), and have a Terraform provider to automate all infrastructure as code (IaC).&lt;/p&gt;
&lt;p&gt;I would have loved working with one of the big three to get deeper experience with them, but the cost, for this project anyway, simply isn&amp;rsquo;t justifiable.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update 2024-10-05: I no longer recommend Scaleway because their Kubernetes cluster spin-up time is very long and they&amp;rsquo;re significantly more expensive than some other good options.  See &lt;a class=&#34;link&#34; href=&#34;../comparison-of-managed-kubernetes-providers-without-egress-fees/&#34; &gt;A Comparison of Managed Kubernetes Providers Without Egress Fees&lt;/a&gt; for details.&lt;/em&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Moving Terraform State from OpenStack Swift to GitLab</title>
        <link>https://colan.pro/blog/moving-terraform-state-from-openstack-swift-to-gitlab/</link>
        <pubDate>Mon, 09 Jan 2023 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/moving-terraform-state-from-openstack-swift-to-gitlab/</guid>
        <description>&lt;img src="https://colan.pro/blog/moving-terraform-state-from-openstack-swift-to-gitlab/terraform.png" alt="Featured image of post Moving Terraform State from OpenStack Swift to GitLab" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/moving-terraform-state-from-openstack-swift-to-gitlab/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For our cloud computing, we typically use an &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenStack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenStack&lt;/a&gt; provider because of its open-source nature: There&amp;rsquo;s no vendor lock-in, and the IaaS code is peer-reviewed unlike providers such as AWS, Azure, GCP, etc.  (Shout out to &lt;a class=&#34;link&#34; href=&#34;https://vexxhost.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vexxhost&lt;/a&gt; for having great support!)  As such, we&amp;rsquo;ve been using OpenStack&amp;rsquo;s Swift object storage service for storing &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Terraform_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform&lt;/a&gt;&amp;rsquo;s state, which allows Terraform to track all of the resources it manages for automating infrastructure.&lt;/p&gt;
&lt;p&gt;Recently, however, support for the Swift backend has been &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform/issues/28957#issuecomment-1260297760&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;removed&lt;/a&gt;.  If you&amp;rsquo;re still using Swift for this purpose, you&amp;rsquo;ll need to migrate your Terraform state files to another backend.  Because &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/v1.3.x/upgrade-guides#migrating-from-the-swift-backend&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the official migration documentation is sparse&lt;/a&gt;, I&amp;rsquo;ll describe how to migrate from Swift to &lt;a class=&#34;link&#34; href=&#34;https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitLab-managed Terraform state&lt;/a&gt;.  GitLab is a fantastic option because it can be used to manage so many other aspects of your project that you need anyway: Git repository hosting, issue tracking, CI/CD, etc.  We use GitLab for all of our projects so it&amp;rsquo;s a great fit for us.&lt;/p&gt;
&lt;p&gt;The actual step of migrating the data is &lt;a class=&#34;link&#34; href=&#34;https://www.terraform.io/language/settings/backends/configuration#initialization&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;well supported&lt;/a&gt;, but there&amp;rsquo;s some required set-up before and after.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you change backends, Terraform gives you the option to migrate your state to the new backend. This lets you adopt backends without losing any existing state.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;prerequisities&#34;&gt;Prerequisities
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Downgrade to the latest pre-1.3 Terraform version.
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;sudo apt install terraform=1.2.9&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to your Terraform directory.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cd /path/to/git/repository/terraform&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Move your local state files out of the way as they could be set up for a different environment.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mv .terraform /tmp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set up your environment variables to connect to use your existing state backend.
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;source ../openstackrc/vexxhost-...-staging-ca-ymq-1.openrc.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initialize Terraform from the remote state.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Back up your current state.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cp .terraform/terraform.tfstate terraform.tfstate.backup-staging&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In your Terraform code, in your &lt;code&gt;backend&lt;/code&gt; stanza, replace &lt;code&gt;swift&lt;/code&gt; with &lt;code&gt;http&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Unset the old state environment variables.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;export TF_CLI_ARGS_init=&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fetch one of your &lt;a class=&#34;link&#34; href=&#34;https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gitlab personal access tokens&lt;/a&gt; with the &lt;code&gt;api&lt;/code&gt; permission.  If you don&amp;rsquo;t have any that aren&amp;rsquo;t expired, create a new one &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/-/profile/personal_access_tokens&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;in your settings&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;setting-variables-in-your-local-environment&#34;&gt;Setting variables in your local environment
&lt;/h2&gt;&lt;p&gt;To actually migrate the data, &lt;a class=&#34;link&#34; href=&#34;https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html#change-the-backend&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the GitLab documentation says to set a single environment variable, and then manually run &lt;code&gt;terraform init&lt;/code&gt; with many options&lt;/a&gt;.  Given that this is error-prone and not easily repeatable, I&amp;rsquo;d recommend using a shell script (or similar) instead.&lt;/p&gt;
&lt;p&gt;Create a file named &lt;code&gt;setup-terraform-variables&lt;/code&gt;, and populate it like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#############################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Set up Terraform variables.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#############################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Set up the Gitlab.com state backend.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OS_PROJECT_CLOUD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_PROJECT_DESCRIPTION&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_PROJECT_ENVIRONMENT&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_REGION_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TF_GITLAB_PROJECT_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;lt;Copy this from your GitLab project page&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Please enter your gitlab.com username: &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; -r TF_GITLAB_USERNAME
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; TF_GITLAB_USERNAME
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Please enter your gitlab.com personal access token: &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; -sr TF_GITLAB_PASSWORD
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; TF_GITLAB_PASSWORD
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TF_STATE_ADDRESS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://gitlab.com/api/v4/projects/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;TF_GITLAB_PROJECT_ID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/terraform/state/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;OS_PROJECT_CLOUD&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TF_CLI_ARGS_init&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;address=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TF_STATE_ADDRESS&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;lock_address=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TF_STATE_ADDRESS&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/lock&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;unlock_address=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TF_STATE_ADDRESS&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/lock&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;username=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TF_GITLAB_USERNAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;password=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TF_GITLAB_PASSWORD&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;lock_method=POST&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;unlock_method=DELETE&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;retry_wait_min=5&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;You can set other Terraform variables in here as well, and include it in other deployment-environment-specific shell scripts that you run to set up each one.  For example, if you&amp;rsquo;re using OpenStack generally, these would be your &lt;a class=&#34;link&#34; href=&#34;https://docs.openstack.org/mitaka/user-guide/common/cli_set_environment_variables_using_openstack_rc.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;openstackrc&lt;/code&gt; files&lt;/a&gt;, which contain your credentials for accessing the API.&lt;/p&gt;
&lt;p&gt;For a further optimization, you can write the GitLab credentials to a local file so as not to have to enter them every time, but I&amp;rsquo;ll leave this as an exercise to the reader.  (If I get a chance, I&amp;rsquo;ll come back here and update it.)&lt;/p&gt;
&lt;h2 id=&#34;changing-the-backend-type&#34;&gt;Changing the backend type
&lt;/h2&gt;&lt;p&gt;In your Terraform configuration files, it&amp;rsquo;s necessary to change the backend type from Swift to HTTP.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; terraform {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gd&#34;&gt;-   backend &amp;#34;swift&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gd&#34;&gt;&lt;/span&gt;&lt;span class=&#34;gi&#34;&gt;+   backend &amp;#34;http&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gi&#34;&gt;&lt;/span&gt;     # Must be read from environment variable `TF_CLI_ARGS_init` because normal
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     # variables cannot be used here.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re wondering why we need to use &lt;code&gt;TF_CLI_ARGS_init&lt;/code&gt;, and can&amp;rsquo;t use Terraform variables in the stanza, see my earlier article &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/blog/setting-environments-terraform-state-backends-with-environment-variables/&#34; &gt; Setting Deployment Environments&amp;rsquo; Terraform State Backends with Environment Variables &lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;migrating-the-data&#34;&gt;Migrating the data
&lt;/h2&gt;&lt;p&gt;You can now run:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You should now see something like this, which requires your confirmation part-way through.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Initializing the backend...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Terraform detected that the backend type changed from &amp;#34;swift&amp;#34; to &amp;#34;http&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Acquiring state lock. This may take a few moments...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Acquiring state lock. This may take a few moments...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Do you want to copy existing state to the new backend?
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Pre-existing state was found while migrating the previous &amp;#34;swift&amp;#34; backend to the
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  newly configured &amp;#34;http&amp;#34; backend. No existing state was found in the newly
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  configured &amp;#34;http&amp;#34; backend. Do you want to copy this state to the new &amp;#34;http&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  backend? Enter &amp;#34;yes&amp;#34; to copy and &amp;#34;no&amp;#34; to start with an empty state.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Enter a value: yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Releasing state lock. This may take a few moments...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Successfully configured the backend &amp;#34;http&amp;#34;! Terraform will automatically
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;use this backend unless the backend configuration changes.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Initializing provider plugins...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Terraform has been successfully initialized!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;You may now begin working with Terraform. Try running &amp;#34;terraform plan&amp;#34; to see
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;any changes that are required for your infrastructure. All Terraform commands
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;should now work.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If you ever set or change modules or backend configuration for Terraform,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rerun this command to reinitialize your working directory. If you forget, other
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;commands will detect it and remind you to do so if necessary.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;resetting-your-local-environment-to-use-the-new-state-storage&#34;&gt;Resetting your local environment to use the new state storage
&lt;/h2&gt;&lt;p&gt;This will purge your old state, and set it up to match the new remote state.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Move your local state files out of the way as they reflect the old state backend.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mv .terraform /tmp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Upgrade Terraform to the latest version.
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;sudo apt install terraform&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set up your environment variables again, using the updated code, to connect to your desired cloud environment.  &lt;em&gt;This script must include &lt;code&gt;setup-terraform-variables&lt;/code&gt; as discussed above.&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;source ../openstackrc/vexxhost-...-staging-ca-ymq-1.openrc.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initialize Terraform from the remote state.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;confirming-the-presense-of-the-remote-state-files&#34;&gt;Confirming the presense of the remote state files
&lt;/h3&gt;&lt;p&gt;You can now see any of your state files in the GitLab Web UI on your Gitlab project&amp;rsquo;s page.  Simply navigate to &lt;code&gt;Infrastructure&lt;/code&gt; -&amp;gt; &lt;code&gt;Terraform&lt;/code&gt;, and they&amp;rsquo;ll be listed.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Setting Deployment Environments&#39; Terraform State Backends with Environment Variables</title>
        <link>https://colan.pro/blog/setting-environments-terraform-state-backends-with-environment-variables/</link>
        <pubDate>Mon, 12 Dec 2022 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/setting-environments-terraform-state-backends-with-environment-variables/</guid>
        <description>&lt;img src="https://colan.pro/blog/setting-environments-terraform-state-backends-with-environment-variables/terraform.png" alt="Featured image of post Setting Deployment Environments&#39; Terraform State Backends with Environment Variables" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/setting-environments-terraform-state-backends-with-environment-variables/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Terraform_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform&lt;/a&gt; is an essential tool for automating cloud-computing infrastructure and storing it in code (&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Infrastructure_as_code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IaC&lt;/a&gt;).  While there are several ways to navigate between deployment environments (e.g. Dev, Staging &amp;amp; Prod), I&amp;rsquo;d like to talk about how this can be done with environment variables, and explain why it can&amp;rsquo;t be done more naturally with Terraform variables.&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background
&lt;/h2&gt;&lt;p&gt;I originally wrote this as &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform/issues/13022#issuecomment-819658436&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a comment&lt;/a&gt; on the feature request &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform/issues/13022&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Using variables in terraform backend config block&lt;/a&gt;, which explains Terraform&amp;rsquo;s design limitations preventing it from allowing any variables in &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/settings/backends/configuration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;backend configurations&lt;/a&gt;, which is what Terraform uses to determine where to store its state data files (which track the cloud resources it manages).&lt;/p&gt;
&lt;p&gt;To illustrate, this is where variables can&amp;rsquo;t be used, even though the configuration must change when the environment changes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;terraform&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;whatever&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[...]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;alternatives-to-using-environment-variables&#34;&gt;Alternatives to using environment variables
&lt;/h2&gt;&lt;p&gt;Alternatively, it&amp;rsquo;s possible to have a single backend state configuration that stores data for multiple environments using &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/state/workspaces&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Workspaces&lt;/a&gt;.  You can then use &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/cli/workspaces&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform CLI commands&lt;/a&gt; to switch between them.  However, this solution is not not appropriate for all use cases, as per the documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Workspaces are not appropriate for system decomposition or deployments requiring separate credentials and access controls.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If this isn&amp;rsquo;t a problem for you, Workspaces is a good option.  Otherwise, please keep reading.&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;In demonstrating a solution, I&amp;rsquo;m going to be working with OpenStack, which is the IaaS run by many cloud providers, but the same concept can be applied to other IaaS, such as AWS, Azure, GCP, etc.  Here, the backend state data will be stored in OpenStack&amp;rsquo;s Swift object storage service.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update (2023-04-11):&lt;/strong&gt; While the example below is still valid conceptually, Swift can no longer be used as a Terraform backend because &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform/issues/28957#issuecomment-1260297760&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;support for it has been removed&lt;/a&gt;.  If you&amp;rsquo;re still using Swift for this purpose, &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/v1.3.x/upgrade-guides#migrating-from-the-swift-backend&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the official migration documentation is sparse&lt;/a&gt;.  However, I provide guidance in a more recent article: &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/blog/moving-terraform-state-from-openstack-swift-to-gitlab/&#34; &gt;Moving Terraform State from OpenStack Swift to GitLab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Typically, you&amp;rsquo;d download an OpenStack RC file, which contains the credentials needed to access the API.  In each of these (e.g. &lt;code&gt;vexxhost-abc-prod-ca.openrc.sh&lt;/code&gt;, where the format is &lt;code&gt;provider-project-environment-region&lt;/code&gt;), I append the following lines to the end:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;...&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#############################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Additional set-up not included with IaaS provider&amp;#39;s OpenStack RC files ###&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#############################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OS_PROJECT_ENVIRONMENT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;abc-prod-ca&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/setup-terraform-variables.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The sourced (included) file then looks like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#############################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Set up Terraform variables.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#############################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Set up backend state container names.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OS_PROJECT_STATE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_PROJECT_ENVIRONMENT&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-terraform-state&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OS_PROJECT_STATE_ARCHIVE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_PROJECT_STATE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-archive&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TF_CLI_ARGS_init&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;container=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_PROJECT_STATE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;-backend-config=&amp;#39;archive_container=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OS_PROJECT_STATE_ARCHIVE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# You can set other TF variables in here as well.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Please enter the outgoing e-mail account&amp;#39;s password: &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt; -sr TF_VAR_smtp_password_unquoted
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TF_VAR_smtp_password&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;\&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TF_VAR_smtp_password_unquoted&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The special environment variable here is &lt;code&gt;TF_CLI_ARGS_init&lt;/code&gt;.  This is what Terraform uses to configure the backend, if it&amp;rsquo;s set.  So by changing that environment variable, you can change the backend configuration.  All that&amp;rsquo;s needed in the code is the following, basically just the backend type, with details being pulled in from the environment.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;main.tf&lt;/code&gt; (or wherever), the backend definition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;terraform&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;swift&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;    # Must be read from environment variable `TF_CLI_ARGS_init` because normal
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;    # variables cannot be used here.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;switching-between-environments&#34;&gt;Switching between environments
&lt;/h2&gt;&lt;p&gt;To switch between environments, I simply source another OpenStack RC file; I have one for every environment that I care about.  With the above set-up, it also switches the Swift object storage containers used for backend state.  You can then run &lt;code&gt;terraform init&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve found that sometimes it&amp;rsquo;s necessary to delete your &lt;code&gt;.terraform&lt;/code&gt; directory before rerunning &lt;code&gt;terraform init&lt;/code&gt; though, or it&amp;rsquo;ll get confused and you&amp;rsquo;ll get strange error messages.  So as standard practise, I run the following command to remove it first:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mv .terraform /tmp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;You cannot use Terraform variables to vary the backend state configuration.&lt;/li&gt;
&lt;li&gt;You can, however, use the environment variable &lt;code&gt;TF_CLI_ARGS_init&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;Run a script to set this environment variable with the configuration matching the deployment environment you&amp;rsquo;d like to work with.&lt;/li&gt;
&lt;li&gt;Simply specify the backend type in the Terraform code, and &lt;code&gt;TF_CLI_ARGS_init&lt;/code&gt; along with your script(s) will take care of the rest.&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>Archives</title>
        <link>https://colan.pro/archives/</link>
        <pubDate>Sun, 06 Mar 2022 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/archives/</guid>
        <description></description>
        </item>
        <item>
        <title>Protecting your cloud networks with WireGuard VPN and Ansible</title>
        <link>https://colan.pro/blog/protecting-cloud-networks-wireguard-ansible/</link>
        <pubDate>Fri, 24 Jul 2020 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/protecting-cloud-networks-wireguard-ansible/</guid>
        <description>&lt;img src="https://colan.pro/blog/protecting-cloud-networks-wireguard-ansible/wireguard.svg" alt="Featured image of post Protecting your cloud networks with WireGuard VPN and Ansible" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/protecting-cloud-networks-wireguard-ansible/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;why-use-a-vpn&#34;&gt;Why use a VPN?
&lt;/h2&gt;&lt;p&gt;Within &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Cloud_computing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cloud computing&lt;/a&gt;, there are various types of sites and services not meant for public consumption (e.g. analytics software, databases, log servers, etc.).  For security reasons, it&amp;rsquo;s best to keep these accesssible only via the private network, which is behind the firewall.&lt;/p&gt;
&lt;p&gt;To provide access to these resources, a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Virtual_private_network&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;virtual private network (VPN)&lt;/a&gt; should be used, with network access granted only to trusted individuals within the organization.&lt;/p&gt;
&lt;h2 id=&#34;why-use-wireguard-specifically&#34;&gt;Why use WireGuard specifically?
&lt;/h2&gt;&lt;p&gt;Traditionally, &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenVPN&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenVPN&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/IPsec&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IPsec&lt;/a&gt; and other solutions were the go-to options within the open-source software space.  However, these are often complex to set up and have relatively massive code bases making them difficult to maintain.&lt;/p&gt;
&lt;p&gt;For example, OpenVPN requires that a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Certificate_authority&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;certificate authority (CA)&lt;/a&gt; be set-up.  This is a complex piece of software, which shouldn&amp;rsquo;t be necessary for running a VPN.  WireGuard simply requires the exchange of &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Public-key_cryptography&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;public keys&lt;/a&gt; in order to set up a secure connection, much like &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenSSH&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SSH&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Pretty_Good_Privacy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;PGP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s been a lot of interest in WireGuard lately, notably because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It was &lt;a class=&#34;link&#34; href=&#34;https://arstechnica.com/gadgets/2020/03/wireguard-vpn-makes-it-to-1-0-0-and-into-the-next-linux-kernel/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;recently added to the Linux kernel&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;NordVPN, one of the major VPN service providers, &lt;a class=&#34;link&#34; href=&#34;https://www.zdnet.com/article/nordvpn-unveils-first-mainstream-wireguard-virtual-private-network/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;has started using it&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Mozilla&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mozilla&lt;/a&gt;, the company behind the Firefox Web browser, &lt;a class=&#34;link&#34; href=&#34;https://blog.mozilla.org/blog/2020/07/15/mozilla-puts-its-trusted-stamp-on-vpn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;just started offering it as a service&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s recommended in &lt;a class=&#34;link&#34; href=&#34;https://paragonie.com/blog/2019/03/definitive-2019-guide-cryptographic-key-sizes-and-algorithm-recommendations&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;The Definitive 2019 Guide to Cryptographic Key Sizes and Algorithm Recommendations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, in the &lt;a class=&#34;link&#34; href=&#34;https://blog.ipfire.org/post/why-not-wireguard&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Why Not WireGuard&lt;/a&gt; article, some opposition was raised.  Let&amp;rsquo;s tackle some of the points raised there.&lt;/p&gt;
&lt;h3 id=&#34;it-does-not-allow-using-a-dynamic-ip-address-on-the-server-side-of-the-tunnel&#34;&gt;It does not allow using a dynamic IP address on the server side of the tunnel
&lt;/h3&gt;&lt;p&gt;Fine, but we&amp;rsquo;re doing the opposite.  The clients can have dynamic IP addresses, but the server never will.  So it&amp;rsquo;s irrelevant for this use case.&lt;/p&gt;
&lt;h3 id=&#34;its-not-easy-to-use-yet&#34;&gt;It&amp;rsquo;s not easy to use yet
&lt;/h3&gt;&lt;p&gt;That&amp;rsquo;s precisely the purpose of this article: To introduce an easy way to set it up and maintain it with &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Ansible_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ansible&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;it-lacks-cipher-agility-and-upgrading-many-clients-is-difficult&#34;&gt;It lacks cipher agility and upgrading many clients is difficult
&lt;/h3&gt;&lt;p&gt;Lacking cipher agility is actually a good thing.  A better approach is to use versioned protocols.  And it&amp;rsquo;s actually no more difficult to upgrade WireGuard clients than anything else.  Both of these non-issues are discussed very nicely in the article &lt;a class=&#34;link&#34; href=&#34;https://paragonie.com/blog/2019/10/against-agility-in-cryptography-protocols&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Against Cipher Agility in Cryptography Protocols&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;trouble-integrating-it-into-linux&#34;&gt;Trouble integrating it into Linux
&lt;/h3&gt;&lt;p&gt;As it was recently added to the Linux kernel, this is no longer an issue.&lt;/p&gt;
&lt;h3 id=&#34;it-lacks-performance&#34;&gt;It lacks performance
&lt;/h3&gt;&lt;p&gt;While performance can always be improved, this doesn&amp;rsquo;t appear to be a critical issue for the application.  For most use cases, it&amp;rsquo;s perfectly usable.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h3&gt;&lt;p&gt;None of the above &amp;ldquo;issues&amp;rdquo; are actually a problem here.&lt;/p&gt;
&lt;h2 id=&#34;why-use-ansible-for-configuration&#34;&gt;Why use Ansible for configuration?
&lt;/h2&gt;&lt;p&gt;Ansible allows for automated deployment of configuration, which removes the need for manually installing, configuring and maintaining applications.  It provides tonnes of modules, including those for files, storage, system, networking and even cloud provisioning (although I would generally recommend &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Terraform_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform&lt;/a&gt; for this purpose).&lt;/p&gt;
&lt;p&gt;Its units of work are called &amp;ldquo;tasks&amp;rdquo; that are run sequentially (procedural) in &amp;ldquo;roles&amp;rdquo; and &amp;ldquo;playbooks&amp;rdquo; to perform operations such as installing server software, its configuration, and  handling various other types of system administration.  Ansible strives for simplicity, resulting in playbooks that are essentially self-documenting.  It can safely be run multiple times (as it strives to be &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Idempotence&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;idempotent&lt;/a&gt;), running tasks only when necessary, leaving already-configured items as-is.&lt;/p&gt;
&lt;h1 id=&#34;a-new-ansible-role&#34;&gt;A new Ansible role
&lt;/h1&gt;&lt;p&gt;While there were &lt;a class=&#34;link&#34; href=&#34;https://galaxy.ansible.com/search?deprecated=false&amp;amp;keywords=wireguard&amp;amp;order_by=-relevance&amp;amp;page=1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;several WireGuard roles available&lt;/a&gt; for installing and maintaining the application, they either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;didn&amp;rsquo;t cater to the cloud gateway VPN use case,&lt;/li&gt;
&lt;li&gt;lacked documentation, and/or&lt;/li&gt;
&lt;li&gt;intentionally omitted critical elements (e.g. &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Packet_forwarding&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;packet forwarding&lt;/a&gt; to internal hosts) for implementation by the user.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As such, I&amp;rsquo;ve written &lt;a class=&#34;link&#34; href=&#34;https://galaxy.ansible.com/consensus/wireguard_cloud_gateway&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a comprehensive one&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s packaged as a &lt;a class=&#34;link&#34; href=&#34;https://docs.ansible.com/ansible/latest/user_guide/collections_using.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;collection&lt;/a&gt; as this is the newer distribution format that doesn&amp;rsquo;t concern itself with the location of source control repositories.  Traditionally, it was necessary for roles to be hosted on &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/GitHub&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt; for them to be published on &lt;a class=&#34;link&#34; href=&#34;https://galaxy.ansible.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Galaxy&lt;/a&gt;, the site for sharing Ansible contributions.  As I prefer &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/GitLab&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitLab&lt;/a&gt; for hosting code repositories, this seemed more natural.  The project is therefore &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/consensus.enterprises/ansible-roles/ansible-role-wireguard-cloud-gateway&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;hosted on GitLab.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The collection contains the single WireGuard role, and can be installed with &lt;code&gt;ansible-galaxy&lt;/code&gt; (Ansible 2.9+).  For older versions of Ansible, simply clone &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/consensus.enterprises/ansible-roles/ansible-role-wireguard-cloud-gateway/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the Git repository&lt;/a&gt; and create a symbolic link to &lt;code&gt;roles/wireguard_cloud_gateway&lt;/code&gt; within it.&lt;/p&gt;
&lt;p&gt;Documentation can be found in &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/consensus.enterprises/ansible-roles/ansible-role-wireguard-cloud-gateway/-/blob/master/roles/wireguard_cloud_gateway/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the role&amp;rsquo;s README&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;key-features&#34;&gt;Key features
&lt;/h1&gt;&lt;h2 id=&#34;support-for-clients-and-servers&#34;&gt;Support for clients and servers
&lt;/h2&gt;&lt;p&gt;Some of the other roles I researched didn&amp;rsquo;t provide much support for configuring the client side of the VPN, meaning the devices which connect to the cloud gateway server to access private network resources.&lt;/p&gt;
&lt;p&gt;My role, on the other hand, can be run in either client or server mode: the same role can be used for configuring both.  Running it in server mode configures the server (on the gateway VM), and running it in client mode configures the client devices (who connect to the server to gain access to the private network).&lt;/p&gt;
&lt;h2 id=&#34;support-for-configured-security-groups&#34;&gt;Support for configured security groups
&lt;/h2&gt;&lt;p&gt;For cloud security akin to traditional &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Firewall_%28computing%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;firewalls&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://patterns.arcitura.com/cloud-computing-patterns/mechanisms/cloud_based_security_groups&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;security groups&lt;/a&gt; are essential for protecting virtual-machine (VM) compute instances.  While these can be configured manually, ideally such configuration would be &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Infrastructure_as_code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;infrastructure as code (IaC)&lt;/a&gt; implemented via a tool such as Terraform, stored in a version control system (VCS) such as Git.&lt;/p&gt;
&lt;p&gt;In a typical VPN-server set-up, the incoming (&amp;ldquo;ingress&amp;rdquo;) rules for such a &amp;ldquo;VPN&amp;rdquo; security group would block access to all ports except the one upon which the VPN communicates.  This configuration should  be applied to the VM that will be running WireGuard.  However, if this is the case, using Ansible to install it won&amp;rsquo;t work because Ansible uses SSH to connect to the VM, and the SSH port is blocked.&lt;/p&gt;
&lt;p&gt;In order to allow for such a secure set-up, a security group ID (e.g. &amp;ldquo;&lt;code&gt;public_ssh&lt;/code&gt;&amp;rdquo;) can be provided to the role as a variable, which will be used to temporarily allow SSH access.  Once the installation is complete, this temporary access will be revoked.&lt;/p&gt;
&lt;h2 id=&#34;support-for-multiple-networks&#34;&gt;Support for multiple networks
&lt;/h2&gt;&lt;p&gt;For those of us that rely on VPN technology, it&amp;rsquo;s often necessary to connect to multiple VPNs at the same time, or at least prevent network resource IDs from overlapping.  For example, you want to avoid having two VMs on different networks from having the same IP address.&lt;/p&gt;
&lt;p&gt;WireGuard supports this by allowing multiple interfaces.  By default, &lt;code&gt;wg0&lt;/code&gt; is used as the first one, but &lt;code&gt;wg1&lt;/code&gt;, &lt;code&gt;wg2&lt;/code&gt;, etc. can all coexist.  If each remote network can exist on a different subnet, there&amp;rsquo;s no conflict from the client perspective.  For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wg0&lt;/code&gt; can be used to access network A, with subnet &lt;code&gt;10.1.0.0/16&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wg1&lt;/code&gt; can be used to access network B, with subnet &lt;code&gt;10.2.0.0/16&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To set this up in your Ansible playbook when calling the role, set the &lt;code&gt;service_interface&lt;/code&gt; variable.  By default, it&amp;rsquo;s &lt;code&gt;wg0&lt;/code&gt;.  Also, be sure to set the &lt;code&gt;client_accessible_ips&lt;/code&gt; properly; this defines the subnet.  For details, see &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/consensus.enterprises/ansible-roles/ansible-role-wireguard-cloud-gateway/-/blob/master/roles/wireguard_cloud_gateway/defaults/main.yml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the default variables file&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;support&#34;&gt;Support
&lt;/h1&gt;&lt;p&gt;The role was originally written for specific systems, notably &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenStack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenStack&lt;/a&gt; networks and Ubuntu VMs.  However, I&amp;rsquo;d like to see the role support as many systems as possible (e.g. the IaaS platforms Amazon Web Services (AWS), Microsoft&amp;rsquo;s Azure, Google Cloud Platform (GCP), Digital Ocean, etc. and non-Debian-based operating systems (OSes) such as CentOS, Red Hat, etc.).&lt;/p&gt;
&lt;p&gt;If you work with these systems, I&amp;rsquo;d be more than happy to accept your supporting code via &lt;a class=&#34;link&#34; href=&#34;https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;merge requests&lt;/a&gt;.  Otherwise, if you&amp;rsquo;re able to provide funding, I can add support for these systems on your behalf.&lt;/p&gt;
&lt;p&gt;To get in touch with me for that, or for any other reason, please use my &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/contact&#34; &gt;contact form&lt;/a&gt;.  I provide consulting in several areas, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enterprise cloud architecture&lt;/li&gt;
&lt;li&gt;Cloud computing infrastructures as a service (IaaS)&lt;/li&gt;
&lt;li&gt;Infrastructure automation with Terraform&lt;/li&gt;
&lt;li&gt;Automating full-stack configuration with Ansible&lt;/li&gt;
&lt;li&gt;OpenStack, Amazon Web Services (AWS), Google Cloud Platform (GCP) &amp;amp; Microsoft Azure consulting&lt;/li&gt;
&lt;li&gt;Virtual private networking (VPNs) with OpenVPN and WireGuard&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Does your Drupal hosting company lack native Composer support?</title>
        <link>https://colan.pro/blog/drupal-hosting-company-lacking-composer-support/</link>
        <pubDate>Thu, 12 Mar 2020 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupal-hosting-company-lacking-composer-support/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupal-hosting-company-lacking-composer-support/composer-plus-aegir.png" alt="Featured image of post Does your Drupal hosting company lack native Composer support?" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/drupal-hosting-company-lacking-composer-support/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Best practices for building Web sites in the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal&lt;/a&gt; framework (for major versions 8 and above) dictate that codebases should be built with the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Composer_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Composer&lt;/a&gt; package manager for PHP.  That is, the code repository for any sites relying on it should not contain any upstream code; it should only contain a makefile with instructions for assembing it.&lt;/p&gt;
&lt;p&gt;However, there are some prominent Drupal hosting companies that don&amp;rsquo;t support Composer natively.  That is, after receiving updates to Composer-controlled Git repositories, they don&amp;rsquo;t automatically rebuild the codebase, which should result in changes to the deployed code.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re hosting your site(s) at one of these companies, and you have this problem, why not consider the obvious alternative?&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir&lt;/a&gt;, the one-and-only open-source hosting system for Drupal that&amp;rsquo;s been around for &lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/blog/aegir_turns_10/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;over 10 years&lt;/a&gt;, has had native Composer support for &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/provision/issues/2937147&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;over 2 years&lt;/a&gt;.  That is, on each and every &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/platforms/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;platform&lt;/a&gt; deployment (&amp;ldquo;platform&amp;rdquo; is Aegir-speak for a Drupal codebase), Aegir reassembles the upstream code assets by running the following automatically:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;composer create-project --no-dev --no-interaction --no-progress
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;As a result, any sites created on that platform (or &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/sites/tasks/#migratingupgrading-sites&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;migrated/upgraded to it&lt;/a&gt;) will have access to all of the assets built by Composer.&lt;/p&gt;
&lt;p&gt;Additionally, Aegir now ships with the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/hosting_deploy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Deploy&lt;/a&gt; module, which enhances the platform creation process.  It allows for the following types of deployment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Classic/None/Manual/Unmanaged&lt;/li&gt;
&lt;li&gt;Drush Makefile deployment&lt;/li&gt;
&lt;li&gt;Pure Git&lt;/li&gt;
&lt;li&gt;Composer deployment from a Git repository&lt;/li&gt;
&lt;li&gt;Composer deployment from a Packagist repository&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information, please read the &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/advanced/deployment/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Deployment Strategies&lt;/a&gt; section of the documentation.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;d like to get started with Aegir, the best option would be to spin up an &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/blog/try-aegir-now-with-the-new-dev-vm/&#34; &gt;Aegir Development VM&lt;/a&gt;, which allows you to run it easily, play with it, and get familiar with the concepts.  Naturally, reading &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the documentation&lt;/a&gt; helps with this too.&lt;/p&gt;
&lt;p&gt;Afterwards, review &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/install/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the installation guide&lt;/a&gt; for more permanent options, and take advantage of our Ansible roles.  We have &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/consensus.enterprises/ansible-roles/ansible-role-aegir-policy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a policy role&lt;/a&gt; that configures &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/consensus.enterprises/ansible-roles/ansible-role-aegir&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the main role&lt;/a&gt; using our favoured approach.&lt;/p&gt;
&lt;p&gt;For help, &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/community/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;contact the community&lt;/a&gt;, or &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/contact&#34; &gt;get in touch with me directly&lt;/a&gt;.  I provide the following Aegir services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installation &amp;amp; maintenance in corporate/enterprise (or other) environments&lt;/li&gt;
&lt;li&gt;Architectural and technical support&lt;/li&gt;
&lt;li&gt;Hosting guidance&lt;/li&gt;
&lt;li&gt;Coaching&lt;/li&gt;
&lt;li&gt;Audits&lt;/li&gt;
&lt;li&gt;Upgrades&lt;/li&gt;
&lt;li&gt;Conversion to best practices&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Aegir 5 is coming, and not just for Drupal!</title>
        <link>https://colan.pro/blog/aegir5-is-coming/</link>
        <pubDate>Tue, 10 Mar 2020 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/aegir5-is-coming/</guid>
        <description>&lt;img src="https://colan.pro/blog/aegir5-is-coming/aegir-logo-banner.svg" alt="Featured image of post Aegir 5 is coming, and not just for Drupal!" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/aegir5-is-coming/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir&lt;/a&gt; is the one-and-only
&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Free_and_open-source_software#FLOSS&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FLOSS&lt;/a&gt;
hosting system for Drupal sites that&amp;rsquo;s been around for over &lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/blog/aegir_turns_10/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;10
years&lt;/a&gt;, a rock in the
community.  While Drupal hosting companies have come and gone, Aegir&amp;rsquo;s always
been there for folks who want to host Drupal sites themselves.  According to
&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/usage/hosting&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;recent data&lt;/a&gt; at the time of this
writing, there are 567 instances (that we know about).&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s used by organizations worldwide such as the US &lt;a class=&#34;link&#34; href=&#34;https://www.ndi.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;National Democratic
Institute&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.nasa.gov/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NASA&lt;/a&gt;, and the
&lt;a class=&#34;link&#34; href=&#34;https://ec.europa.eu/info/index_en&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;European Commission&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir 3&lt;/a&gt; is the currently stable
recommended major release, we&amp;rsquo;ve started working on Aegir 5, which is a
complete rewrite.  It has notable differences such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drush.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drush&lt;/a&gt;, traditionally used as &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/provision&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the provisioner&lt;/a&gt;, has been replaced by &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Ansible_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ansible&lt;/a&gt;, which allows for the hosting of any type of site or service, not just Drupal.&lt;/li&gt;
&lt;li&gt;The front-end, formerly Drupal 7, has been replaced by Drupal 8, which allows us to take advantage of all of the newer features it provides.&lt;/li&gt;
&lt;li&gt;Components are now best-of-breed open-source tools such as &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Celery_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Celery&lt;/a&gt;, for the task queue.  When Aegir was originally written, tools such as Ansible and Celery didn&amp;rsquo;t exist so all of the functionality was written as Aegir-specific code.  We can now get off that island.&lt;/li&gt;
&lt;li&gt;The entire project is now maintained in &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a single code repository&lt;/a&gt;, unlike the traditional four (&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/hosting&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hosting&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/Provision&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Provision&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/hostmaster&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hostmaster&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/eldir&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Eldir&lt;/a&gt;) that have been maintained historically.&lt;/li&gt;
&lt;li&gt;An &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir/-/issues/32&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;out-of-the-box framework&lt;/a&gt; for automatic site updates via the &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/advanced/distributions/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Distributions&lt;/a&gt; concept.  This was experimental in Aegir 3.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While still maintaining Aegir 3, we&amp;rsquo;d like to direct any new development
initiatives towards the more modern Aegir 5.&lt;/p&gt;
&lt;p&gt;The initial focus is on supporting Drupal.  We then intend to add support for
&lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir/-/issues/16&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Matomo&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir/-/issues/36&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hugo&lt;/a&gt;, and other applications we
use.  However, documentation has been started on &lt;a class=&#34;link&#34; href=&#34;http://docs.aegir.hosting/dev/extending/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;how to add support for
anything else&lt;/a&gt; so merge requests or
funding for new apps are greatly encouraged.&lt;/p&gt;
&lt;p&gt;Along with the &lt;a class=&#34;link&#34; href=&#34;http://docs.aegir.hosting/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;main documentation site&lt;/a&gt;, which
includes &lt;a class=&#34;link&#34; href=&#34;http://docs.aegir.hosting/dev/architecture/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the architecture&lt;/a&gt;, there
is also &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir/-/boards&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;an issues board&lt;/a&gt; for tracking
tickets.&lt;/p&gt;
&lt;p&gt;While we&amp;rsquo;re working on it as quickly as we can, we sometimes get delayed by
other priorities.  As such, we&amp;rsquo;re actively looking for sponsors to help us
prioritize development.  Please get in touch if you&amp;rsquo;re interested in
partnering, collaborating, providing funding, or anything else.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Installing the OpenStack CLI on Ubuntu 19.10 (Eoan), 20.04 (Focal) or later</title>
        <link>https://colan.pro/blog/install-openstack-cli-ubuntu-1910/</link>
        <pubDate>Mon, 09 Mar 2020 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/install-openstack-cli-ubuntu-1910/</guid>
        <description>&lt;img src="https://colan.pro/blog/install-openstack-cli-ubuntu-1910/openstack-logo-2016.png" alt="Featured image of post Installing the OpenStack CLI on Ubuntu 19.10 (Eoan), 20.04 (Focal) or later" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/install-openstack-cli-ubuntu-1910/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When working with &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenStack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenStack&lt;/a&gt; as an infrastructure-as-a-service (IaaS) &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Cloud_computing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cloud-computing&lt;/a&gt; platform, it&amp;rsquo;s rather convenient to be able to interface with it via &lt;a class=&#34;link&#34; href=&#34;https://docs.openstack.org/python-openstackclient/latest/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;its command-line interface (CLI)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While the service is typically installed on the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Ubuntu&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ubuntu Long-Term Support (LTS)&lt;/a&gt; operating system (OS), which has releases every two years, running the CLI from other OSes, such as interim Ubuntu releases, is often necessary.  However, it is currently not possible to install the command-line client with supported Debian packages on Ubuntu 19.10.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update (2020-05-30)&lt;/strong&gt;&lt;/em&gt;: The simplest way to install the OpenStack CLI nowadays, at least on Ubuntu 20.04 (Focal) and later, is via &lt;a class=&#34;link&#34; href=&#34;https://snapcraft.io/install/openstackclients/ubuntu&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the Snap package&lt;/a&gt;.  Debian packages are no longer made available:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo snap install openstackclients --classic
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This should be all you need to do; there&amp;rsquo;s no reason to follow the instructions in the remaining portion of this article.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update (2021-08-18)&lt;/strong&gt;&lt;/em&gt;: You may run into the following error on Ubuntu 21.04:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;% openstack versions show
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Traceback &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;most recent call last&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  File &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/local/bin/openstack&amp;#34;&lt;/span&gt;, line 5, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    from openstackclient.shell import main
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ModuleNotFoundError: No module named &lt;span class=&#34;s1&#34;&gt;&amp;#39;openstackclient&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you do, run the following commands:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;sudo apt install pip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo pip install python_openstackclient&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Openstack commands should start working again.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Attempting to follow &lt;a class=&#34;link&#34; href=&#34;https://docs.openstack.org/install-guide/environment-packages-ubuntu.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the instructions in the documentation&lt;/a&gt; for the two listed OpenStack releases, which require an additional software archive, results in the message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cloud-archive for Rocky only supported on bionic&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cloud-archive for Stein only supported on bionic&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In addition, attempting to use the native software repository is impossible because &lt;a class=&#34;link&#34; href=&#34;https://packages.ubuntu.com/disco/python-openstackclient&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the package isn&amp;rsquo;t available&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As such, I&amp;rsquo;ve written a short script to fetch and install all of the necessary Debian packages from another release.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DEST_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/tmp/openstack-cli-debs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-netaddr/python-netaddr_0.7.19-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-iso8601/python-iso8601_0.1.11-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/pyinotify/python-pyinotify_0.9.6-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-monotonic/python-monotonic_1.5-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-oslo.context/python-oslo.context_2.22.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-warlock/python-warlock_1.2.0-2_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/s/stevedore/python-stevedore_1.30.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-os-service-types/python-os-service-types_1.6.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-oslo.config/python-oslo.config_6.8.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-debtcollector/python-debtcollector_1.20.0-2_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-oslo.log/python-oslo.log_3.42.3-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-os-client-config/python-os-client-config_1.31.2-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-requestsexceptions/python-requestsexceptions_1.4.0-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-deprecation/python-deprecation_2.0.6-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-dogpile.cache/python-dogpile.cache_0.6.2-6_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-json-patch/python-jsonpatch_1.21-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-munch/python-munch_2.3.2-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-openstackclient/python-openstackclient_3.18.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-cinderclient/python-cinderclient_4.1.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-cliff/python-cliff_2.14.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-glanceclient/python-glanceclient_2.16.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-keystoneauth1/python-keystoneauth1_3.13.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-keystoneclient/python-keystoneclient_3.19.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-neutronclient/python-neutronclient_6.11.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-novaclient/python-novaclient_13.0.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-openstacksdk/python-openstacksdk_0.26.0-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/universe/p/python-osc-lib/python-osc-lib_1.12.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-oslo.i18n/python-oslo.i18n_3.23.1-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-oslo.serialization/python-oslo.serialization_2.28.2-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -cP &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt; http://mirrors.kernel.org/ubuntu/pool/main/p/python-oslo.utils/python-oslo.utils_3.40.3-0ubuntu1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dpkg -i &lt;span class=&#34;nv&#34;&gt;$DEST_DIR&lt;/span&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt --fix-broken install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Hopefully this helps other folks who have also run into this issue.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Drupal North 2019: Drupal SaaS: Building software as a service on Drupal</title>
        <link>https://colan.pro/blog/drupal-saas-building-software-as-a-service-on-drupal/</link>
        <pubDate>Fri, 15 Nov 2019 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupal-saas-building-software-as-a-service-on-drupal/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupal-saas-building-software-as-a-service-on-drupal/saas-icon.png" alt="Featured image of post Drupal North 2019: Drupal SaaS: Building software as a service on Drupal" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/drupal-saas-building-software-as-a-service-on-drupal/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;On Friday, June 14th, I presented &lt;a class=&#34;link&#34; href=&#34;https://drupalnorth.org/en/session/drupal-saas-building-software-service-drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this session&lt;/a&gt; at &lt;a class=&#34;link&#34; href=&#34;https://drupalnorth.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal North 2019&lt;/a&gt;. That&amp;rsquo;s the annual gathering of the Drupal community in Ontario and Quebec, in Canada.&lt;/p&gt;
&lt;p&gt;As I realized I hadn&amp;rsquo;t yet posted this information yet, I&amp;rsquo;m doing so now.&lt;/p&gt;
&lt;p&gt;Session information:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are you (considering) building a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Software_as_a_service&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SaaS&lt;/a&gt; product on &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal&lt;/a&gt; or running a Drupal hosting company?  Have you done it already?  Come share your experiences and learn from others.&lt;/p&gt;
&lt;p&gt;Among other things, we&amp;rsquo;ll be discussing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Project vs. product business&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/docs/8/distributions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Installation profiles / distributions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customer service (e.g. &lt;a class=&#34;link&#34; href=&#34;https://about.gitlab.com/product/service-desk/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitLab&amp;rsquo;s Service Desk&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Hosting architecture (&lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/drupal-specific-hosting-choose-provider-those-offering-comprehensive-platforms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal hosting companies&lt;/a&gt; vs. &lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Infrastructure (&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Infrastructure_as_a_service&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IaaS&lt;/a&gt; hosting providers: &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenStack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenStack&lt;/a&gt; vs. AWS, GCS, Azure, etc.)&lt;/li&gt;
&lt;li&gt;E-commerce, recurring billing and subscription provider integration
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/aegir_site_subscriptions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Site Subscriptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Others?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resource quotas&lt;/li&gt;
&lt;li&gt;Site admin access permissions for clients&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip;and any other related topics that come up.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A video recording of my presentation is available on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://drupal.tv/external-video/2019-06-15/drupal-saas-building-software-service-drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal.tv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=2XN3J3X1GGw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My slides (with clickable links) are available on &lt;a class=&#34;link&#34; href=&#34;https://talks.consensus.enterprises/2019-drupalnorth-drupal-saas/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;our presentations site&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Exposing Drupal&#39;s Taxonomy Data on the Semantic Web</title>
        <link>https://colan.pro/blog/exposing-drupal-taxonomy-data-sematic-web/</link>
        <pubDate>Thu, 24 Oct 2019 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/exposing-drupal-taxonomy-data-sematic-web/</guid>
        <description>&lt;img src="https://colan.pro/blog/exposing-drupal-taxonomy-data-sematic-web/semantic-spider-web.jpg" alt="Featured image of post Exposing Drupal&#39;s Taxonomy Data on the Semantic Web" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/exposing-drupal-taxonomy-data-sematic-web/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As a content management framework, &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal&lt;/a&gt; provides strong support for its &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/docs/user_guide/en/structure-taxonomy.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;taxonomical subsystem for classifying data&lt;/a&gt;.  It would be great if such data could be exposed via the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Simple_Knowledge_Organization_System&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Simple Knowledge Organization System (SKOS)&lt;/a&gt; standard for publishing vocabularies as &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Linked_data&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;linked data&lt;/a&gt;.  As Drupal becomes used more and more as a back-end data store (due to features such as &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/blog/jsonapi-lands-in-drupal-core&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;built-in support for JSON:API&lt;/a&gt;), presenting this data in standard ways becomes especially important.&lt;/p&gt;
&lt;p&gt;So is this actually possible now?  If not, what remains to be done?&lt;/p&gt;
&lt;h2 id=&#34;drupals-history&#34;&gt;Drupal&amp;rsquo;s history
&lt;/h2&gt;&lt;p&gt;First, let&amp;rsquo;s explore some of Drupal core&amp;rsquo;s history as it relates to the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Semantic_Web&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Semantic Web&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Web_service&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Web services&lt;/a&gt; formats, also useful for future reference.   This is basically the backstory that makes all of this possible.&lt;/p&gt;
&lt;h3 id=&#34;rest-support-was-added-to-views&#34;&gt;REST support was added to Views
&lt;/h3&gt;&lt;p&gt;This was implemented in the (now closed) issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/drupal/issues/1819760&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Add a REST export display plugin and serializer integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/drupal/issues/1857256&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Convert the taxonomy listing and feed at /taxonomy/term/%term to Views&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;non-schemaorg-namespace-mappings-were-removed-including-contribs-ui-support-in-drupal-8&#34;&gt;Non-Schema.org namespace mappings were removed (including contrib&amp;rsquo;s UI support) in Drupal 8
&lt;/h3&gt;&lt;p&gt;Here&amp;rsquo;s the change notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/drupal/issues/1784234&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Use schema.org types and properties in RDF mappings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And a follow-up issue requesting support for additional namespaces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/rdfui/issues/2386777&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Allow usage of any namespace in RDF mapping UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;the-community-chose-to-replace-json-ld-with-hal-in-drupal-8&#34;&gt;The community chose to replace JSON-LD with HAL in Drupal 8
&lt;/h3&gt;&lt;p&gt;Here&amp;rsquo;s an article with the details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://dev.acquia.com/blog/decoupling-drupal-8-core-web-services-in-core-and-the-serialization-module/20/03/2018/19271&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Decoupling Drupal 8 Core: Web Services in Core and the Serialization Module&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://colan.pro/images/blog/banners/example-vocabulary-vehicles.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Taxonomy Screenshot&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;multiple-components&#34;&gt;Multiple Components
&lt;/h2&gt;&lt;p&gt;As this is really a two-part issue, adding machine-readable metadata and then making machine-readable data available, I&amp;rsquo;ll split the discussion into two sections.&lt;/p&gt;
&lt;h2 id=&#34;adding-machine-readable-metadata&#34;&gt;Adding machine-readable metadata
&lt;/h2&gt;&lt;p&gt;While there&amp;rsquo;s an &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/rdfui&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RDF UI&lt;/a&gt; module that enables one to specify mappings between Drupal entities and their fields with RDF types and properties, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/rdfui/issues/2386777&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;it only supports Schema.org&lt;/a&gt; via RDFa (not JSON-LD).&lt;/p&gt;
&lt;p&gt;As explained very well in &lt;a class=&#34;link&#34; href=&#34;https://www.lullabot.com/articles/create-seo-juice-by-adding-json-ld-structured-data-to-drupal-8&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Create SEO Juice From JSON LD Structured Data in Drupal&lt;/a&gt;, a better solution is to use the framework provided by the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/metatag&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Metatag&lt;/a&gt; module (used by modules such as &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/agls&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AGLS Metadata&lt;/a&gt;).  The article introduces the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/schema_metatag&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Schema.org Metatag&lt;/a&gt; module, which uses the Metatag UI to allow users to map Drupal data to Schema.org, &lt;em&gt;and exposes it via JSON-LD&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So one solution would be to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone Schema.org Metatag, calling the new module &lt;em&gt;SKOS Metatag&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Replace all of the Schema.org specifics with SKOS.&lt;/li&gt;
&lt;li&gt;Rejoice.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But after taking some time to process all of the above information, I believe we should be able to use the knowledge of the vocabulary hierarchy to  add the SKOS metadata.  We probably don&amp;rsquo;t need any admin UI at all for configuring mappings.&lt;/p&gt;
&lt;p&gt;Assuming that&amp;rsquo;s true, we can instead create a SKOS module that doesn&amp;rsquo;t depend on Metatag, but Metatag may still be useful given that it already &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2563647&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;supports Views&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;making-the-machine-readable-data-available&#34;&gt;Making the machine-readable data available
&lt;/h2&gt;&lt;p&gt;Exposing the site&amp;rsquo;s data can be done best though &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/docs/8/core/modules/views/overview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Views&lt;/a&gt;.  I wouldn&amp;rsquo;t recommend doing this any other way, e.g. accessing nodes (Drupal-speak for records) directly, or through any default taxonomy links for listing all of a vocabulary&amp;rsquo;s terms.  (These actually are Views, but their default set-ups are missing configuration.)  A good recipe for getting this up &amp;amp; running, for both the list and individual items, is available at &lt;a class=&#34;link&#34; href=&#34;https://drupalize.me/blog/201402/your-first-restful-view-drupal-8&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Your First RESTful View in Drupal 8&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To actually access the data from elsewhere, you need to be aware of the recent API change &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2954953&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;To access REST export views, one now MUST specify a ?_format=… query string&lt;/a&gt;, which explains why some consumers broke.&lt;/p&gt;
&lt;p&gt;The JSON-LD format is, however, not supported in Core by default.  There is some code in a couple of sandboxes, which may or may not work, that will need to be ported to the official module, brought up-to-date, and have a release (ideally stable) cut.  See the issue &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/jsonld/issues/2799305&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;JSON-LD REST Services: Port to Drupal 8&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;Now, the Metatag solution I proposed in the previous section may work with Views natively, already exposing data as JSON-LD.  If that&amp;rsquo;s the case, this JSON-LD port may not be necessary, but this remains to be seen.  Also, accessing the records directly (without Views) may work as well, but this also remains to be seen after that solution is developed.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Clearly, there&amp;rsquo;s more work to be done.  While the ultimate goal hasn&amp;rsquo;t been achieved yet, at least we have a couple of paths forward.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s as far as I got with pure research.  Due to priorities shifting on the client project, I didn&amp;rsquo;t get a chance to learn more by reviewing the code and testing it to see what does and doesn&amp;rsquo;t work, which would be the next logical step.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve got a project that could make use of any of this, please reach out.  We&amp;rsquo;d love to help move this technology further along and get it implemented.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References
&lt;/h2&gt;&lt;h3 id=&#34;general-information&#34;&gt;General information
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/questions/14307792/what-is-the-relationship-between-rdf-rdfa-microformats-and-microdata&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;What is the relationship between RDF, RDFa, Microformats and Microdata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.quora.com/What-is-the-difference-between-Microdata-RDFa-JSON-LD&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;What is the difference between Microdata, RDFa &amp;amp; JSON-LD?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;contributed-modules-that-probably-arent-helpful-but-could-be&#34;&gt;Contributed modules that probably aren&amp;rsquo;t helpful (but could be)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/structured_data&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Structured Data (JSON+LD Rich Snippets)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/json_ld_schema&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;JSON LD Schema API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/wisski&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;WissKI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/ontology&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ontology&lt;/a&gt; (OWL)&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/dcat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DCAT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/rdf_entity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RDF entity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/drupal2rdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal2RDF&lt;/a&gt; (This is brand new, but at the time of this writing, there&amp;rsquo;s not enough info/code yet to figure out what it&amp;rsquo;s trying to do.)&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s a module called &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/smart_glossary&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Smart Glossary&lt;/a&gt; which allows you to have multilingual SKOS Thesauri on your Drupal site, but I don&amp;rsquo;t think it&amp;rsquo;s useful at all as it&amp;rsquo;s part of a suite of modules maintained by &lt;a class=&#34;link&#34; href=&#34;https://www.poolparty.biz/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;PoolParty&lt;/a&gt;, where they expect you to use their data store:
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/smart_glossary&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Smart Glossary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/pp_taxonomy_manager&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;PoolParty Taxonomy Manager for Drupal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/semantic_connector&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Semantic Connector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/powertagging&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;PowerTagging&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;questions-about-importing-skos-data-not-exporting-it&#34;&gt;Questions about importing SKOS data (not exporting it)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://groups.drupal.org/node/516739&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Options for SKOS integration in Drupal 8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/forum/support/post-installation/2017-05-08/how-can-i-work-with-skos-data&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;How can I work with SKOS data?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Aegir DevOps: Deployment Workflows for Drupal Sites</title>
        <link>https://colan.pro/blog/aegir-devops-deployment-workflows-drupal-sites/</link>
        <pubDate>Tue, 24 Sep 2019 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/aegir-devops-deployment-workflows-drupal-sites/</guid>
        <description>&lt;img src="https://colan.pro/blog/aegir-devops-deployment-workflows-drupal-sites/brain-web-640.jpg" alt="Featured image of post Aegir DevOps: Deployment Workflows for Drupal Sites" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/aegir-devops-deployment-workflows-drupal-sites/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir&lt;/a&gt; is often seen as a stand-alone &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Application_lifecycle_management&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;application lifecycle management (ALM)&lt;/a&gt; system for hosting and managing &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal&lt;/a&gt; sites.  In the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Enterprise_software&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;enterprise context&lt;/a&gt;, however, it&amp;rsquo;s necessary to provide mutiple &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Deployment_environment&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;deployment environments&lt;/a&gt; for &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Quality_assurance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;quality assurance (QA)&lt;/a&gt;, development or other purposes.  Aegir trivializes this process by allowing sites to easily be copied from one environment to another in a point-and-click fashion from the Web front-end, eliminating the need for &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Command-line_interface&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;command-line&lt;/a&gt; &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/DevOps&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DevOps&lt;/a&gt; tasks, which it was designed to do.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-the-environments&#34;&gt;Setting up the environments
&lt;/h2&gt;&lt;p&gt;An Aegir instance needs to be installed in each environment.  We would typically have three (3) of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Development (Dev)&lt;/strong&gt;: While generally reserved for integration testing, it is sometimes also used for development (e.g. when local environments cannot be used by developers or there are a small number of them).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Staging&lt;/strong&gt;: Used for QA purposes.  Designed to be a virtual clone of Production to ensure that tagged releases operate the same way as they would there, before being made live.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Production (Prod)&lt;/strong&gt;: The live environment visible to the public or the target audience, and the authoritative source for data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(While outside the scope of this article, local development environments can be set up as well.  See &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/blog/try-aegir-now-with-the-new-dev-vm/&#34; &gt;Try Aegir now with the new Dev VM&lt;/a&gt; for details.)&lt;/p&gt;
&lt;p&gt;To install Aegir in each of these, follow the &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/install/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;installation instructions&lt;/a&gt;.  For larger deployments, common architectures for Staging and Prod would include features such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Separate Web and database servers&lt;/li&gt;
&lt;li&gt;Multiple Web and database servers&lt;/li&gt;
&lt;li&gt;Load balancers&lt;/li&gt;
&lt;li&gt;Caching/HTTPS proxies&lt;/li&gt;
&lt;li&gt;Separate partitions for (external) storage of:
&lt;ul&gt;
&lt;li&gt;The Aegir file system (&lt;code&gt;/var/aegir&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Site backups (&lt;code&gt;/var/aegir/backups&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Database storage (&lt;code&gt;/var/lib/mysql&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As these are all out of scope for the purposes of this article, I&amp;rsquo;ll save these discussions for the future, and assume we&amp;rsquo;re working with default installations.&lt;/p&gt;
&lt;h2 id=&#34;allowing-the-environments-to-communicate&#34;&gt;Allowing the environments to communicate
&lt;/h2&gt;&lt;p&gt;To enable inter-environment communication, we must perform the following series of tasks on each Aegir VM as part of the initial set-up, which only needs to be done once.&lt;/p&gt;
&lt;h3 id=&#34;back-end-set-up&#34;&gt;Back-end set-up
&lt;/h3&gt;&lt;p&gt;The back-ends of each instance must be able to communicate.  For that we use the secure &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Secure_Shell&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SSH protocol&lt;/a&gt;.  As stated on Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SSH is important in cloud computing to solve connectivity problems, avoiding the security issues of exposing a cloud-based virtual machine directly on the Internet. An SSH tunnel can provide a secure path over the Internet, through a firewall to a virtual machine.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
Steps to enable SSH communication:
&lt;ol&gt;
&lt;li&gt;SSH into the VM.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh ENVIRONMENT.aegir.example.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Become the Aegir user.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo -sHu aegir&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generate an SSH key.  (If you&amp;rsquo;ve done this already to access a private Git repository, you can skip this step.)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096 -C &amp;quot;ORGANIZATION Aegir ENVIRONMENT&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For every other environment from where you&amp;rsquo;d like to fetch sites:
&lt;ol&gt;
&lt;li&gt;Add the generated public key (&lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt;) to the whitelist for the Aegir user on the other VM so that the original instance can connect to this target.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh OTHER_ENVIRONMENT.aegir.example.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo -sHu aegir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vi ~/.ssh/authorized_keys&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;exit&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Back on the original VM, allow connections to the target VM.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo -sHu aegir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ssh OTHER_ENVIRONMENT.aegir.example.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Answer affirmatively when asked to confirm the host (after verifying the fingerprint, etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;front-end-set-up&#34;&gt;Front-end set-up
&lt;/h3&gt;&lt;p&gt;These steps will tell Aegir about the other Aegir servers whose sites can be imported.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On Aegir&amp;rsquo;s front-end Web UI, the &amp;ldquo;hostmaster&amp;rdquo; site, enable remote site imports by navigating to &lt;em&gt;Administration » Hosting » Advanced&lt;/em&gt;, and check the &lt;em&gt;Remote import&lt;/em&gt; box.  Save the form.  (This enables the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/hosting_remote_import&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Hosting Remote Import&lt;/a&gt; module.)&lt;/li&gt;
&lt;li&gt;For every other server you&amp;rsquo;d like to add, do the following:
&lt;ol&gt;
&lt;li&gt;Navigate to the &lt;em&gt;Servers&lt;/em&gt; tab, and click on the &lt;em&gt;Add server&lt;/em&gt; link.&lt;/li&gt;
&lt;li&gt;For the &lt;em&gt;Server hostname&lt;/em&gt;, enter the hostname of the other Aegir server (e.g. &lt;code&gt;staging.aegir.example.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click the &lt;em&gt;Remote import&lt;/em&gt; vertical tab, check &lt;em&gt;Remote hostmaster&lt;/em&gt;, and then enter &lt;code&gt;aegir&lt;/code&gt; for the &lt;em&gt;Remote user&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;For the &lt;em&gt;Human-readable name&lt;/em&gt;, you can enter something like &lt;code&gt;Foo&#39;s Staging Aegir&lt;/code&gt; (assuming the Staging instance).&lt;/li&gt;
&lt;li&gt;You can generally ignore the &lt;em&gt;IP addresses&lt;/em&gt; section.&lt;/li&gt;
&lt;li&gt;Hit the &lt;em&gt;Save&lt;/em&gt; button.&lt;/li&gt;
&lt;li&gt;Wait for the server verification to complete successfully.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of the one-time command-line tasks are now done.  You or your users can now use the Web UI to shuffle site data between environments.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://colan.pro/images/blog/banners/aegir-select-remote-site-to-import.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Select remote site to import&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;deploying-sites-from-one-environment-to-another&#34;&gt;Deploying sites from one environment to another
&lt;/h2&gt;&lt;p&gt;Whenever necessary, this point-and-click process can be used to deploy sites from one Aegir environment to another.  It&amp;rsquo;s actually a pull method as the destination Aegir instance imports a site from the source.&lt;/p&gt;
&lt;p&gt;Reasons to do this include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The initial deployment of a development site from Dev to Prod.&lt;/li&gt;
&lt;li&gt;Refreshing Dev and Staging sites from Prod.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you&amp;rsquo;d like to install the site onto a new &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/platforms/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;platform&lt;/a&gt; that&amp;rsquo;s not yet available, &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/platforms/#getting-a-platform-onto-your-server&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;create the platform&lt;/a&gt; first.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;em&gt;Servers&lt;/em&gt; tab.&lt;/li&gt;
&lt;li&gt;Click on the server hosting the site you&amp;rsquo;d like to import.&lt;/li&gt;
&lt;li&gt;Click on the &lt;em&gt;Import remote sites&lt;/em&gt; link.&lt;/li&gt;
&lt;li&gt;Follow the prompts.&lt;/li&gt;
&lt;li&gt;Wait for the batch job, Import and Verify tasks to complete.&lt;/li&gt;
&lt;li&gt;Enable the imported site by hitting the &lt;em&gt;Run&lt;/em&gt; button on the &lt;em&gt;Enable&lt;/em&gt; task.&lt;/li&gt;
&lt;li&gt;The imported site is now ready for use!&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>Try Aegir now with the new Dev VM</title>
        <link>https://colan.pro/blog/try-aegir-now-with-the-new-dev-vm/</link>
        <pubDate>Mon, 09 Sep 2019 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/try-aegir-now-with-the-new-dev-vm/</guid>
        <description>&lt;img src="https://colan.pro/blog/try-aegir-now-with-the-new-dev-vm/aegir-logo-banner.svg" alt="Featured image of post Try Aegir now with the new Dev VM" /&gt;&lt;p&gt;&lt;em&gt;Originally published on the &lt;a class=&#34;link&#34; href=&#34;https://consensus.enterprises/blog/try-aegir-now-with-the-new-dev-vm/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Consensus Enterprises blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Have you been looking for a self-hosted solution for hosting and managing Drupal sites?  Would you like be able able to upgrade all of your sites at once with a single button click?  Are you tired of dealing with all of the proprietary Drupal hosting providers that won&amp;rsquo;t let you customize your set-up?  Wouldn&amp;rsquo;t it be nice if all of your sites had free automatically-updating HTTPS certificates?  You probably know that &lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir&lt;/a&gt; can do all of this, but it&amp;rsquo;s now trivial to set up a temporary trial instance to see how it works.&lt;/p&gt;
&lt;p&gt;The new &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir-dev-vm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Development VM&lt;/a&gt; makes this possible.&lt;/p&gt;
&lt;h2 id=&#34;history&#34;&gt;History
&lt;/h2&gt;&lt;p&gt;Throughout Aegir&amp;rsquo;s history, we&amp;rsquo;ve had several projects striving to achieve the same goal.  They&amp;rsquo;re listed in the &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/extend/contrib/#development&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Contributed Projects section of the documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;aegir-up&#34;&gt;Aegir Up
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/aegir_up&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Up&lt;/a&gt; was based on a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/VirtualBox&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VirtualBox&lt;/a&gt; &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Virtual_machine&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;virtual machine (VM)&lt;/a&gt;, managed by &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Vagrant_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vagrant&lt;/a&gt; and provisioned with &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Puppet_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Puppet&lt;/a&gt;.  It was superseded by Valkyrie (see below).&lt;/p&gt;
&lt;h3 id=&#34;aegir-development-environment&#34;&gt;Aegir Development Environment
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/aegir-project/development&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Development Environment&lt;/a&gt; took a completely different approach using &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Docker_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Docker&lt;/a&gt;.  It assembles all of the services (each one in a container, e.g. the MySQL database) into a system managed by Docker Compose.  While this is a novel approach, it&amp;rsquo;s not necessary to have multiple containers to get a basic Aegir instance up and running.&lt;/p&gt;
&lt;h3 id=&#34;valkyrie&#34;&gt;Valkyrie
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/valkyrie&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Valkyrie&lt;/a&gt; was similar to Aegir Up, but provisioning moved from Puppet to &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Ansible_%28software%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ansible&lt;/a&gt;.  Valkyrie also made extensive use of custom &lt;a class=&#34;link&#34; href=&#34;http://www.drush.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drush&lt;/a&gt; commands to simplify development.&lt;/p&gt;
&lt;p&gt;Its focus was more on developing Drupal sites than on developing Aegir.  Now that we have &lt;a class=&#34;link&#34; href=&#34;https://docs.devwithlando.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Lando&lt;/a&gt;, it&amp;rsquo;s no longer necessary to include this type of functionality.&lt;/p&gt;
&lt;p&gt;It was superseded by the now current Aegir Development VM.&lt;/p&gt;
&lt;h2 id=&#34;present&#34;&gt;Present
&lt;/h2&gt;&lt;p&gt;Like Valkyrie, the Aegir Development VM is based on a VirtualBox VM (but that&amp;rsquo;s not the only option; see below) managed with Vagrant and provisioned with Ansible.  However, it doesn&amp;rsquo;t rely on custom Drush commands.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://colan.pro/images/blog/banners/aegir-dev-vm-screenshot.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;features&#34;&gt;Features
&lt;/h2&gt;&lt;h3 id=&#34;customizable-configuration&#34;&gt;Customizable configuration
&lt;/h3&gt;&lt;p&gt;The Aegir Development VM configuration is very easy to customize as &lt;a class=&#34;link&#34; href=&#34;https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ansible variables&lt;/a&gt; are used &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir-dev-vm/blob/master/ansible/playbook.yml#L6&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;throughout&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, if you&amp;rsquo;d like to use &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Nginx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Nginx&lt;/a&gt; instead of &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Apache_HTTP_Server&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apache&lt;/a&gt;, simply replace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aegir_http_service_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;apache&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&amp;hellip;with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aegir_http_service_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&amp;hellip;or &lt;a class=&#34;link&#34; href=&#34;https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#passing-variables-on-the-command-line&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;override using the command line&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir-dev-vm/blob/master/ansible/playbook.yml#L11&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;install and enable additional Aegir modules&lt;/a&gt; from &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/extend/contrib/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the available set&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;support-for-remote-vms&#34;&gt;Support for remote VMs
&lt;/h3&gt;&lt;p&gt;For those folks with older hardware who are unable to spare extra gigabytes (GB) for VMs, it&amp;rsquo;s possible to set up the VM remotely.&lt;/p&gt;
&lt;p&gt;While the default amount of RAM necessary is 1 GB, 2 GB would be better for any serious work, and 4 GB is necessary if &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/usage/platforms/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;creating platforms&lt;/a&gt; &lt;a class=&#34;link&#34; href=&#34;https://git.drupalcode.org/project/hosting_deploy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;directly from Packagist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Support for &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/DigitalOcean&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DigitalOcean&lt;/a&gt; is included, but other &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Infrastructure_as_a_service&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IaaS&lt;/a&gt; providers (e.g. &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenStack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenStack&lt;/a&gt;) can be added later.  Patches welcome!&lt;/p&gt;
&lt;h3 id=&#34;fully-qualified-domain-name-fqdn-not-required&#34;&gt;Fully qualified domain name (FQDN) not required
&lt;/h3&gt;&lt;p&gt;While Aegir can quickly be installed with a small number of commands in the &lt;a class=&#34;link&#34; href=&#34;https://docs.aegirproject.org/quick-start/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Quick Start Guide&lt;/a&gt;, that process requires an &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Fully_qualified_domain_name&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FQDN&lt;/a&gt;, usually something like &lt;code&gt;aegir.example.com&lt;/code&gt; (which requires global &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Domain_Name_System&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DNS&lt;/a&gt; configuration).  That is not the case with the Dev VM, which assumes &lt;code&gt;aegir.local&lt;/code&gt; by default.&lt;/p&gt;
&lt;h3 id=&#34;simplified-development&#34;&gt;Simplified development
&lt;/h3&gt;&lt;p&gt;You can use it for Aegir development as well as trying Aegir!&lt;/p&gt;
&lt;p&gt;Unlike the default set-up provisioned by the Quick Start Guide, which would require additional configuration, the individual components (e.g. &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/hosting&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hosting&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/provision&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Provision&lt;/a&gt;, etc.) are cloned repositories making it easy to create patches (and for module maintainers: push changes upstream).&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;We&amp;rsquo;ve recently updated the project so that &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir-dev-vm/issues/8&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;an up-to-date VM is being used&lt;/a&gt;, and it&amp;rsquo;s now ready for general use.  Please go ahead and try it.&lt;/p&gt;
&lt;p&gt;If you run into any problems, feel free to create issues on &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir-dev-vm/boards&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the issue board&lt;/a&gt; and/or submit &lt;a class=&#34;link&#34; href=&#34;https://docs.gitlab.com/ee/user/project/merge_requests/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;merge requests&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>DrupalCamp Ottawa 2018: Drupal SaaS: Building software as a service on Drupal</title>
        <link>https://colan.pro/blog/drupalcamp-ottawa-2018-drupal-saas-building-software-service-drupal/</link>
        <pubDate>Fri, 26 Oct 2018 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupalcamp-ottawa-2018-drupal-saas-building-software-service-drupal/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupalcamp-ottawa-2018-drupal-saas-building-software-service-drupal/new-banner.jpg" alt="Featured image of post DrupalCamp Ottawa 2018: Drupal SaaS: Building software as a service on Drupal" /&gt;&lt;p&gt;On Friday, October 26th, I presented at &lt;a class=&#34;link&#34; href=&#34;https://drupalcampottawa.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DrupalCamp Ottawa 2018&lt;/a&gt;, the annual gathering of the Drupal community in Ottawa, Ontario, Canada.&lt;/p&gt;
&lt;h2 id=&#34;session-information&#34;&gt;Session Information
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Are you (considering) building a SaaS product on Drupal or running a Drupal hosting company? Have you done it already? Come share your experiences and learn from others.&lt;/p&gt;
&lt;p&gt;Among other things, we&amp;rsquo;ll be discussing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Project vs. product business&lt;/li&gt;
&lt;li&gt;Installation profiles / distributions&lt;/li&gt;
&lt;li&gt;Customer service (e.g. GitLab&amp;rsquo;s Service Desk)&lt;/li&gt;
&lt;li&gt;Hosting architecture (Drupal hosting companies vs. Aegir)&lt;/li&gt;
&lt;li&gt;Infrastructure (IaaS hosting providers: OpenStack vs. AWS, GCS, Azure, etc.)&lt;/li&gt;
&lt;li&gt;E-commerce, recurring billing and subscription provider integration
&amp;gt;   - Aegir Site Subscriptions
&lt;ul&gt;
&lt;li&gt;Others?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resource quotas&lt;/li&gt;
&lt;li&gt;Site admin access permissions for clients&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&amp;hellip;and any other related topics that come up.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources
&lt;/h2&gt;&lt;p&gt;A video recording of our presentation is available on &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=HMe9GFMag8Y&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;YouTube&lt;/a&gt; (with the audio track missing, unfortunately), and my slides (with clickable links) are available at &lt;a class=&#34;link&#34; href=&#34;https://talks.consensus.enterprises/drupal-saas&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;talks.consensus.enterprises/drupal-saas&lt;/a&gt;.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Drupal North Toronto 2018: Hosting Drupal Sites? You need Aegir</title>
        <link>https://colan.pro/blog/drupal-north-toronto-2018-hosting-drupal-sites-you-need-aegir/</link>
        <pubDate>Sat, 18 Aug 2018 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupal-north-toronto-2018-hosting-drupal-sites-you-need-aegir/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupal-north-toronto-2018-hosting-drupal-sites-you-need-aegir/new-banner.webp" alt="Featured image of post Drupal North Toronto 2018: Hosting Drupal Sites? You need Aegir" /&gt;&lt;p&gt;On Saturday, August 11th, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/ergonlogic&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Christopher Gervais&lt;/a&gt; and I presented at &lt;a class=&#34;link&#34; href=&#34;https://drupalnorth.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal North 2018&lt;/a&gt;, the annual gathering of the Drupal community in southern Ontario and Quebec, Canada.&lt;/p&gt;
&lt;h2 id=&#34;session-information&#34;&gt;Session Information
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Do you need a self-hosted solution for hosting and managing Drupal sites? Would you like to be able to upgrade all of your sites at once with a single button click? Are you tired of dealing with all of the proprietary Drupal hosting providers that won&amp;rsquo;t let you customize your set-up? Wouldn&amp;rsquo;t it be nice if all of your sites could automatically get free HTTPS certificates?&lt;/p&gt;
&lt;p&gt;If you said yes to any of the above questions, there&amp;rsquo;s only one option: the &lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Hosting System&lt;/a&gt;. While it&amp;rsquo;s possible to &lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/drupal-specific-hosting-choose-provider-those-offering-comprehensive-platforms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;find a company that will host Drupal sites for you&lt;/a&gt;, Aegir helps you maintain control whether you want to use your own infrastructure or manage your own software-as-a-service (SaaS) product. Plus, you get all the &lt;a class=&#34;link&#34; href=&#34;https://opensource.com/article/17/8/enterprise-open-source-advantages&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;benefits of open source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;History&lt;/li&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Basic features&lt;/li&gt;
&lt;li&gt;Advanced features&lt;/li&gt;
&lt;li&gt;Development workflows&lt;/li&gt;
&lt;li&gt;Recent additions&lt;/li&gt;
&lt;li&gt;Future&lt;/li&gt;
&lt;li&gt;Questions &amp;amp; discussion&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources
&lt;/h2&gt;&lt;p&gt;A one-hour video recording of our presentation is available on &lt;a class=&#34;link&#34; href=&#34;https://m.youtube.com/watch?v=Ie31O9qBOgI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;YouTube&lt;/a&gt;, and our slides (with clickable links) are attached here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;Hosting-Drupal-sites-You-need-Aegir.pdf&#34; &gt;Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>DrupalCamp Montreal 2018: Hosting Drupal Sites? You need Aegir</title>
        <link>https://colan.pro/blog/drupalcamp-montreal-2018-hosting-drupal-sites-you-need-aegir/</link>
        <pubDate>Fri, 15 Jun 2018 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupalcamp-montreal-2018-hosting-drupal-sites-you-need-aegir/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupalcamp-montreal-2018-hosting-drupal-sites-you-need-aegir/new-banner.webp" alt="Featured image of post DrupalCamp Montreal 2018: Hosting Drupal Sites? You need Aegir" /&gt;&lt;p&gt;On Friday, June 15th, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/ergonlogic&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Christopher Gervais&lt;/a&gt; and I presented at &lt;a class=&#34;link&#34; href=&#34;https://drupalcampmontreal.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DrupalCamp Montreal 2018&lt;/a&gt;, the annual gathering of the Drupal community in Montreal, Canada.&lt;/p&gt;
&lt;h2 id=&#34;session-information&#34;&gt;Session Information
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Do you need a self-hosted solution for hosting and managing Drupal sites? Would you like to be able to upgrade all of your sites at once with a single button click? Are you tired of dealing with all of the proprietary Drupal hosting providers that won&amp;rsquo;t let you customize your set-up? Wouldn&amp;rsquo;t it be nice if all of your sites could automatically get free HTTPS certificates?&lt;/p&gt;
&lt;p&gt;If you said yes to any of the above questions, there&amp;rsquo;s only one option: the &lt;a class=&#34;link&#34; href=&#34;https://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Hosting System&lt;/a&gt;. While it&amp;rsquo;s possible to &lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/drupal-specific-hosting-choose-provider-those-offering-comprehensive-platforms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;find a company that will host Drupal sites for you&lt;/a&gt;, Aegir helps you maintain control whether you want to use your own infrastructure or manage your own software-as-a-service (SaaS) product. Plus, you get all the &lt;a class=&#34;link&#34; href=&#34;https://opensource.com/article/17/8/enterprise-open-source-advantages&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;benefits of open source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;History&lt;/li&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Basic features&lt;/li&gt;
&lt;li&gt;Advanced features&lt;/li&gt;
&lt;li&gt;Development workflows&lt;/li&gt;
&lt;li&gt;Recent additions&lt;/li&gt;
&lt;li&gt;Future&lt;/li&gt;
&lt;li&gt;Questions &amp;amp; discussion&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources
&lt;/h2&gt;&lt;p&gt;A one-hour video recording of our presentation is available on &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=_-fJupSTKa4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;YouTube&lt;/a&gt;, and our slides (with clickable links) are attached here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;Hosting-Drupal-sites-You-need-Aegir.pdf&#34; &gt;Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>DrupalTO Aegir Presentation</title>
        <link>https://colan.pro/blog/drupalto-aegir-presentation/</link>
        <pubDate>Fri, 01 Jun 2018 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupalto-aegir-presentation/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupalto-aegir-presentation/new-banner.webp" alt="Featured image of post DrupalTO Aegir Presentation" /&gt;&lt;p&gt;On Tuesday, May 29th, I presented at a DrupalTO meetup, the monthly gathering of the Toronto Drupal users&amp;rsquo; group.&lt;/p&gt;
&lt;h2 id=&#34;session-information&#34;&gt;Session Information
&lt;/h2&gt;&lt;p&gt;The presentation focused on the Aegir Hosting System for managing Drupal sites. For more information, see the &lt;a class=&#34;link&#34; href=&#34;https://www.meetup.com/DrupalTO/events/251053717&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;event&lt;/a&gt;. My slides are attached.&lt;/p&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;Hosting-Drupal-sites-You-need-Aegir.pdf&#34; &gt;Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Aegir: Your open-source hosting platform for Drupal sites</title>
        <link>https://colan.pro/blog/aegir-your-open-source-hosting-platform-drupal-sites/</link>
        <pubDate>Thu, 07 Dec 2017 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/aegir-your-open-source-hosting-platform-drupal-sites/</guid>
        <description>&lt;img src="https://colan.pro/blog/aegir-your-open-source-hosting-platform-drupal-sites/new-banner.png" alt="Featured image of post Aegir: Your open-source hosting platform for Drupal sites" /&gt;&lt;p&gt;If you need an open-source solution for hosting and managing Drupal sites, there&amp;rsquo;s only one option: the &lt;a class=&#34;link&#34; href=&#34;http://www.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir Hosting System&lt;/a&gt;. While it&amp;rsquo;s possible to find a company that will &lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/drupal-specific-hosting-choose-provider-those-offering-comprehensive-platforms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;host Drupal sites for you&lt;/a&gt;, Aegir helps you maintain control whether you want to use your own infrastructure or manage your own software-as-a-service (SaaS) product. Plus, you get all the &lt;a class=&#34;link&#34; href=&#34;https://web.archive.org/web/20231002012933/https://opensource.com/article/17/8/enterprise-open-source-advantages&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;benefits of open source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aegir turns ten today. The first commit occurred on December 7th, 2007. We&amp;rsquo;ve actually produced &lt;a class=&#34;link&#34; href=&#34;http://tenyears.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a timeline&lt;/a&gt; including all major historical events. While Aegir had a slow uptake (the usability wasn&amp;rsquo;t great in the early days), it&amp;rsquo;s now being used by all kinds of organizations, &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=vsAOjP5iIhQ&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;including NASA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I got involved in the project a couple of years ago when I needed a hosting solution for a project I was working on. I started by improving &lt;a class=&#34;link&#34; href=&#34;http://docs.aegirproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the documentation&lt;/a&gt;, working on &lt;a class=&#34;link&#34; href=&#34;http://docs.aegirproject.org/en/3.x/extend/contrib/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;contributed modules&lt;/a&gt;, and then eventually the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/hostmaster&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;core system&lt;/a&gt;. I&amp;rsquo;ve been using it ever since for all of my SaaS projects and have been taking the lead on Drupal 8 e-commerce integration. I became a &lt;a class=&#34;link&#34; href=&#34;http://docs.aegirproject.org/en/3.x/community/core-team/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;core maintainer&lt;/a&gt; of the project about a year and a half ago.&lt;/p&gt;
&lt;p&gt;So what&amp;rsquo;s new with the project? We&amp;rsquo;ve got several initiatives on the go. While Aegir 3 is stable and usable now (&lt;a class=&#34;link&#34; href=&#34;http://www.aegirproject.org/#download&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Download it!&lt;/a&gt;), we&amp;rsquo;ve started moving away from &lt;a class=&#34;link&#34; href=&#34;https://web.archive.org/web/20231002012933/https://github.com/drush-ops/drush&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drush&lt;/a&gt;, which traditionally handles the heavy lifting (see &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/provision/issues/2911855&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Provision: Drupal 8.4 support&lt;/a&gt; for details), and into a couple of different directions. We&amp;rsquo;ve got an &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2912579&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Aegir 4 branch based on Symfony&lt;/a&gt;, which is also included in Drupal core. This is intended to be a medium-term solution until Aegir 5 (codenamed AegirNG), a complete rewrite for hosting any application, is ready. Neither of these initiatives is stable yet, but development is ongoing. Feel free to peruse &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/aegir/aegir/wikis/architecture&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the AegirNG architecture document&lt;/a&gt;, which is publicly available.&lt;/p&gt;
&lt;p&gt;Please watch this space for future articles on the subject. I plan on writing about the following Aegir-related topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Managing your development workflow across Aegir environments&lt;/li&gt;
&lt;li&gt;Automatic HTTPS-enabled sites with Aegir&lt;/li&gt;
&lt;li&gt;Remote site management with Aegir Services&lt;/li&gt;
&lt;li&gt;Preventing clients from changing Aegir site configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy Birthday Aegir! It&amp;rsquo;s been a great ten years.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Representing Drupal at the GSoC 2017 Mentor Summit</title>
        <link>https://colan.pro/blog/representing-drupal-gsoc-2017-mentor-summit/</link>
        <pubDate>Thu, 26 Oct 2017 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/representing-drupal-gsoc-2017-mentor-summit/</guid>
        <description>&lt;img src="https://colan.pro/blog/representing-drupal-gsoc-2017-mentor-summit/new-banner.png" alt="Featured image of post Representing Drupal at the GSoC 2017 Mentor Summit" /&gt;&lt;p&gt;I&amp;rsquo;ve been mentoring students as part of &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal&lt;/a&gt;&amp;rsquo;s &lt;a class=&#34;link&#34; href=&#34;https://summerofcode.withgoogle.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Summer of Code (GSoC)&lt;/a&gt; program for the last two years, where we guide students in working on Drupal projects over the summer. (For the projects I&amp;rsquo;ve been involved in, see &lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/client-side-encryption-options-now-available-drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;User-friendly encryption now in Drupal 8!&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/client-side-encryption-options-now-available-drupal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Client-side encryption options now available in Drupal&lt;/a&gt;.) This year, our organization administrator, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/slurpee&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Matthew Lechleider&lt;/a&gt;, invited me to the &lt;a class=&#34;link&#34; href=&#34;https://developers.google.com/open-source/gsoc/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mentor Summit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Google-provided summit creates a forum for members of &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Free_and_open-source_software&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;free/libre and open-source software (FLOSS)&lt;/a&gt; organizations to come together to discuss GSoC, mentoring, and FLOSS in an &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Unconference&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;unconference&lt;/a&gt; format. I met attendees from all over the world, who flew in from far-reaching places to interact as part of a wider community. Generally, two mentors are invited from each organization, but some had more and some had less.&lt;/p&gt;
&lt;p&gt;I arrived late Friday night, having missed that day&amp;rsquo;s introductory sessions due to some trouble at the US border. Historically, in my experience, we Canadians haven&amp;rsquo;t had too much trouble getting across the border for technology conferences. This has recently changed so it&amp;rsquo;s now necessary to provide proof of intent for being in the country (a signed invitation from the organizers) as well as proof of business activities (corporate and tax documents). Needless to say, all of this took a significant amount of time to prepare. Eventually though, I was allowed through and made my way to Sunnyvale, California.&lt;/p&gt;
&lt;p&gt;On Saturday morning, the day started with Lightning Talks, where attendees gave presentations on their student projects having only a few minutes each to speak. There were so many presentations that it was necessary to split the session into two, continuing after dinner that same evening. While there were several interesting projects highlighted, the most interesting to me was &lt;a class=&#34;link&#34; href=&#34;https://jitsi.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Jitsi&lt;/a&gt;&amp;rsquo;s &lt;a class=&#34;link&#34; href=&#34;https://jitsi.org/news/speech-to-text-a-summer-of-code-success-story/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;speech-to-text service&lt;/a&gt;. Besides making video conferences accessible through textual media, it also allows for automated note-taking. This was one of the truly amazing projects completed by a student over the summer.&lt;/p&gt;
&lt;p&gt;In talking about Drupal with other folks, I was surprised to hear that many other delegates do not have paying day jobs associated with their organizations. They work on these projects on the side, and generally don&amp;rsquo;t get paid for them. For example, nobody in the &lt;a class=&#34;link&#34; href=&#34;https://kodi.tv/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Kodi&lt;/a&gt; contributor community gets paid; it&amp;rsquo;s all volunteer work. While there are volunteer contributions to Drupal, many of those contributors eventually turn that knowledge into paid work. I suppose we&amp;rsquo;re a lucky bunch, being able to work on an open-source project and get paid for it. And speaking of Kodi, I&amp;rsquo;m happy to report that they&amp;rsquo;re using Drupal for their website!&lt;/p&gt;
&lt;p&gt;There were quite a few conversations about messaging applications, with a large &lt;a class=&#34;link&#34; href=&#34;https://xmpp.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;XMPP&lt;/a&gt; delegation. There were also folks from the &lt;a class=&#34;link&#34; href=&#34;https://zulip.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Zulip&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://rocket.chat/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Rocket.Chat&lt;/a&gt; communities. It was interesting to hear from a former XMPP developer who&amp;rsquo;s shifted completely to &lt;a class=&#34;link&#34; href=&#34;https://matrix.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Matrix&lt;/a&gt; with the &lt;a class=&#34;link&#34; href=&#34;https://element.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Riot&lt;/a&gt; client, exactly as I&amp;rsquo;ve done. I use that client and the federated protocol to bridge with other communications networks such as proprietary closed-source &lt;a class=&#34;link&#34; href=&#34;https://slack.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Slack&lt;/a&gt; and classic &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Internet_Relay_Chat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Internet Relay Chat (IRC)&lt;/a&gt; whenever possible. Matrix already integrates with these two protocols, and has built-in support. The goal is to eventually use only one messaging client, instead of the many applications we all have installed on all of our devices. Rocket.Chat has already started working on Matrix integration, while Zulip hasn&amp;rsquo;t. They&amp;rsquo;re open to it, and may move in this direction eventually, but for now they&amp;rsquo;re focused on user-experience innovations. In the Drupal community, we&amp;rsquo;ve had &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2490332&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a very long discussion&lt;/a&gt; about using Matrix for our communications alongside IRC, and have finally put &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/matrixchat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a plan into place to make this happen&lt;/a&gt;. For those eager to jump in, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2906243&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;it&amp;rsquo;s now possible to use Matrix as an always-on IRC bouncer client&lt;/a&gt; to connect to &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/irc&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal&amp;rsquo;s IRC channels&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Alongside Drupal, representatives from other &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Content_management_system&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;content management systems (CMSes)&lt;/a&gt; also attended. There were folks from both the Joomla and Plone communities. It would have been great to connect with them, but I didn&amp;rsquo;t get a chance. I was hoping that &lt;a class=&#34;link&#34; href=&#34;https://airshipcms.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Airship CMS&lt;/a&gt; would have representation as that crew has been doing a lot of excellent security work with PHP projects (including &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/docs/develop/security&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;helping us&lt;/a&gt; with Drupal), but they weren&amp;rsquo;t in attendance.&lt;/p&gt;
&lt;p&gt;All in all, it was an excellent conference. In my humble opinion, it&amp;rsquo;s really important to stay in touch with this greater community, cross-pollinate with folks doing similar work in the public interest, and keep contributing!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Client-side encryption options now available in Drupal</title>
        <link>https://colan.pro/blog/client-side-encryption-options-now-available-drupal/</link>
        <pubDate>Mon, 18 Sep 2017 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/client-side-encryption-options-now-available-drupal/</guid>
        <description>&lt;img src="https://colan.pro/blog/client-side-encryption-options-now-available-drupal/new-banner.webp" alt="Featured image of post Client-side encryption options now available in Drupal" /&gt;&lt;p&gt;After the success of &lt;a class=&#34;link&#34; href=&#34;https://colan.pro/blog/user-friendly-encryption-now-drupal-8&#34; &gt;last year&amp;rsquo;s GSOC project with Drupal&lt;/a&gt;, I thought it would be a great idea to see if we could take what we did there (server-side encryption) and do something similar on &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Client-side_encryption&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the client side&lt;/a&gt;. The benefit of this approach is that unencrypted content/data is never seen by the hosting server. So it&amp;rsquo;s not necessary to trust it to the same degree. This has been &lt;a class=&#34;link&#34; href=&#34;https://drupal.stackexchange.com/questions/88925/what-are-the-alternatives-for-storing-client-side-encrypted-data&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;a requested feature&lt;/a&gt; for some time, and become very popular within &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Comparison_of_instant_messaging_clients#Messengers_with_client-to-client_encryption&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the instant-messaging space&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I posted &lt;a class=&#34;link&#34; href=&#34;https://groups.drupal.org/node/515848#project1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the idea&lt;/a&gt;, but wasn&amp;rsquo;t sure how much traction there would be given the additional complexity. Before long, there were two interested students, &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/marncz&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Marcin Czarnecki&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/tameeshb&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tameesh Biswas&lt;/a&gt;, who were interested in the project given their interest in cryptography. They both wrote very good proposals, which we in the Drupal community accepted.&lt;/p&gt;
&lt;p&gt;With the help of &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/nerdstein&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Adam Bergstein&lt;/a&gt; (my co-mentor from last year) and &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/talhaparacha&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Talha Paracha&lt;/a&gt; (last year&amp;rsquo;s student), we were able to mentor both students in working towards completing their projects, even with the added complexity. Unlike last year, users&amp;rsquo; passwords couldn&amp;rsquo;t be used to encrypt anything because the site has access to these. An out-of-band mechanism was necessary to perform the encryption, &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Public-key_cryptography&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;public-key cryptography&lt;/a&gt;. It needed to be in the hands of users themselves instead of being handled implicitly by the server.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m delighted to report that both students passed. The community can now take their projects and build upon them. Please review the new Drupal modules at &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/encrypt_content_client&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Client-side content encryption&lt;/a&gt; (&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2901707&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;overview&lt;/a&gt;) and &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/client_side_file_crypto&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Client Side File Crypto&lt;/a&gt; (&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2904242&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;overview&lt;/a&gt;). If there are any issues, please open tickets in the respective queues.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>User-friendly encryption now in Drupal 8!</title>
        <link>https://colan.pro/blog/user-friendly-encryption-now-drupal-8/</link>
        <pubDate>Mon, 12 Sep 2016 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/user-friendly-encryption-now-drupal-8/</guid>
        <description>&lt;img src="https://colan.pro/blog/user-friendly-encryption-now-drupal-8/DALL%C2%B7E%202024-06-24%2015.41.32%20-%20A%20vibrant,%20wide%20banner%20image%20representing%20data%20encryption%20and%20security,%20featuring%20elements%20like%20locks,%20keys,%20and%20encrypted%20data%20symbols,%20with%20a%20focus%20.webp" alt="Featured image of post User-friendly encryption now in Drupal 8!" /&gt;&lt;p&gt;The problem with most encryption strategies nowadays is that they require third-party software and/or services, require maintenance of additional keys and/or secrets, and provide an awful user experience.&lt;/p&gt;
&lt;p&gt;Earlier this year, I started wondering why we couldn&amp;rsquo;t simply encrypt data with pre-existing secrets, the passwords users already have for logging into their Drupal sites. They shouldn&amp;rsquo;t have to deal with public and private keys and other cryptographic details. So I did some research, and was happy to discover that the security model is already in existence. The folks at &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OwnCloud&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ownCloud&lt;/a&gt; have not only published it (&lt;a class=&#34;link&#34; href=&#34;https://owncloud.com/wp-content/uploads/2014/10/Overview_of_ownCloud_Encryption_Model_1.1.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Data Encryption Model 1.1&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://owncloud.com/wp-content/uploads/2015/07/Overview_of_ownCloud_Encryption_Model_2.2.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;2.2&lt;/a&gt;); they&amp;rsquo;ve already implemented it in their product. What&amp;rsquo;s even better is that the product is also written in PHP like Drupal, and has &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;an open-source license&lt;/a&gt;. So the ideas and code can be reused.&lt;/p&gt;
&lt;p&gt;Not too long after I made this discovery, the Drupal community was looking for project ideas for &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/google-summer-of-code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google&amp;rsquo;s Summer of Code (GSOC)&lt;/a&gt;. So &lt;a class=&#34;link&#34; href=&#34;https://groups.drupal.org/node/508466#project30&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;I added mine to the list&lt;/a&gt;. There were several students interested in the topic, and wrote proposals to match. &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/talhaparacha&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Talha Paracha&lt;/a&gt;&amp;rsquo;s excellent &lt;a class=&#34;link&#34; href=&#34;https://summerofcode.withgoogle.com/projects/#6125392490397696&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;proposal&lt;/a&gt; was accepted, and he began in earnest. With &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/nerdstein&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Adam Bergstein (nerdstein)&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/u/colan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;I&lt;/a&gt; mentoring him, Talha successfully worked though all phases of the project. For details, please see his &lt;a class=&#34;link&#34; href=&#34;http://www.talhaparacha.com/blog-posts/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;blog posts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now that GSOC 2016 has come to a close, we have a full project release for the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/pubkey_encrypt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Pubkey Encrypt&lt;/a&gt; module. It&amp;rsquo;s currently in beta, awaiting community review before we publish a production-ready version. We&amp;rsquo;ve included an architecture document, user stories, and usage documentation. There&amp;rsquo;s also a video! Please take the time to experiment with the module, and create tickets for any issues that you find.&lt;/p&gt;
&lt;p&gt;At the time of this writing, only field data can be encrypted via the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/field_encrypt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Field Encryption&lt;/a&gt; module. The &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/file_encrypt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;File Encryption&lt;/a&gt; module is still in development, but as soon as it&amp;rsquo;s released, it should work with Pubkey Encrypt as well.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Authenticating Drupal users via OAuth2</title>
        <link>https://colan.pro/blog/authenticating-drupal-users-oauth2/</link>
        <pubDate>Sun, 06 Sep 2015 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/authenticating-drupal-users-oauth2/</guid>
        <description>&lt;img src="https://colan.pro/blog/authenticating-drupal-users-oauth2/DALL%C2%B7E%202024-06-24%2016.05.18%20-%20A%20vibrant,%20wide%20banner%20image%20representing%20OAuth2%20authentication%20for%20Drupal,%20featuring%20elements%20like%20locks,%20keys,%20and%20dat.webp" alt="Featured image of post Authenticating Drupal users via OAuth2" /&gt;&lt;p&gt;I recently had a client that began delegating access to all of its data assets across the enterprise network via &lt;a class=&#34;link&#34; href=&#34;https://oauth.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth&lt;/a&gt;, specifically the OAuth 2.0 protocol. While I was there architecting a Drupal solution as their new Web platform, they wanted me to hook into this system to authenticate their Drupal users. Although there have been some modules available in the ecosystem to support OAuth2, there weren&amp;rsquo;t any available to provide this functionality. So I created the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/oauth2_authentication&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth2 Authentication&lt;/a&gt; module.&lt;/p&gt;
&lt;p&gt;This module allows users to log into a Drupal site authenticating against a remote &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Identity_provider&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;identity provider (IDP)&lt;/a&gt; via &lt;a class=&#34;link&#34; href=&#34;https://oauth.net/2/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth2&lt;/a&gt;. That is, if a user&amp;rsquo;s credentials can be used to retrieve a valid &lt;a class=&#34;link&#34; href=&#34;https://oauth.net/2/access-tokens/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;access token&lt;/a&gt;, he/she will be logged into the site with those credentials and the token will be added to his/her session. If the user account doesn&amp;rsquo;t exist yet, it will be created.&lt;/p&gt;
&lt;p&gt;In doing this, we&amp;rsquo;re making the assumption that resource requesters are actually resource owners. Generally, one shouldn&amp;rsquo;t make that assumption as OAuth2 is an authorization mechanism, not an authentication mechanism. Ideally, logging in users via OAuth2 should be done with &lt;a class=&#34;link&#34; href=&#34;https://openid.net/connect/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenID Connect&lt;/a&gt;. It provides a proper identity layer on top of OAuth2. It&amp;rsquo;s essentially the evolution of &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/SAML_2.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SAML&lt;/a&gt;; see &lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/questions/22470159/can-oauth-2-be-used-for-sso-or-do-i-need-a-more-sophisticated-authentication/24739510#24739510&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;my answer&lt;/a&gt; to &lt;a class=&#34;link&#34; href=&#34;http://stackoverflow.com/q/22470159/442022&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Can OAuth 2 be used for SSO? Or do I need a more sophisticated authentication?&lt;/a&gt; for details. In situations where one doesn&amp;rsquo;t have access to an OpenID Connect server, but does have access to an IDP that speaks OAuth2 and can trust the environment in which all of it operates, this module is sufficient.&lt;/p&gt;
&lt;p&gt;The security implications of using this module should be well understood. If one doesn&amp;rsquo;t control the environment in which it&amp;rsquo;s running, then it shouldn&amp;rsquo;t be used. For example, I don&amp;rsquo;t recommend running with this concept in a mobile environment as it can&amp;rsquo;t be trusted to the same extent as a Drupal site behind a corporate firewall. The following articles are on the subject are noteworthy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://blog.api-security.org/2013/02/why-oauth-it-self-is-not-authentication.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Why OAuth it self is not an authentication framework?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;The problem with OAuth for Authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also wouldn&amp;rsquo;t hurt to study the official &lt;a class=&#34;link&#34; href=&#34;https://datatracker.ietf.org/doc/html/rfc6819&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth 2.0 Threat Model and Security Considerations&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;initial-set-up&#34;&gt;Initial Set-Up
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Install and enable the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/oauth2_client&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth2 Client&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/oauth2_authentication&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth2 Authentication&lt;/a&gt; modules as you would any other.&lt;/li&gt;
&lt;li&gt;If you wish to override any of the methods in the OAuth2AuthenticationClient class to change the module&amp;rsquo;s behaviour, create another class that extends it and implement the desired methods. This is best done in a custom module for your site, something like Sitename Authentication (sitename_authentication) where S/sitename is the name of your site.&lt;/li&gt;
&lt;li&gt;Surf to the configuration page over at Home » Administration » Configuration » Web services » OAuth2 Authentication to configure your token endpoint. This section is mandatory while the others are optional. They contain sane defaults, but look over all of it to make sure it&amp;rsquo;s what you need for your set-up.&lt;/li&gt;
&lt;li&gt;If you subclassed OAuth2AuthenticationClient, replace the default class name in Miscellaneous Settings » Client Class with the name of your new class.&lt;/li&gt;
&lt;li&gt;Hit the Save configuration button to save your settings.&lt;/li&gt;
&lt;li&gt;Enjoy!&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;notes&#34;&gt;Notes
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Once you&amp;rsquo;ve got this set up, you&amp;rsquo;ll have to ensure that &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/wsclient&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the Web-services client module you&amp;rsquo;re using&lt;/a&gt; supports the OAuth2 protocol (i.e., token access to resources). If you&amp;rsquo;re already using one that doesn&amp;rsquo;t, you&amp;rsquo;ll have to add that support. Otherwise, go with one that supports this already.&lt;/li&gt;
&lt;li&gt;When an existing local user logs in, the module will attempt to get an access token for him/her. On success, the token will be added to the user&amp;rsquo;s session. On failure, the user will still be logged in, but will not get a token. Whenever a request to get a token is made, the results are reported in the log.&lt;/li&gt;
&lt;li&gt;If an existing user whose password has changed on the IDP, but not Drupal yet, logs in, the password hash stored locally will be updated. This is attempted after a local login failure: If the user can authenticate remotely, the account is updated locally, and the user is logged in normally. There are no noticeable differences to the end user.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;issues&#34;&gt;Issues
&lt;/h2&gt;&lt;h3 id=&#34;token-expiration&#34;&gt;Token Expiration
&lt;/h3&gt;&lt;p&gt;If the total expiration time for your tokens, including successive tokens returned by your token server through refresh tokens (RTs), is less than the maximum time a user can be logged in (see &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/session_expire&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Session Expire&lt;/a&gt; for details), users will still be logged in when their final tokens expire.&lt;/p&gt;
&lt;p&gt;As this module doesn&amp;rsquo;t (yet) deal with that situation, you&amp;rsquo;ll need to come up with a solution that meets your requirements. Some background information on this can be found over at &lt;a class=&#34;link&#34; href=&#34;https://rnd.feide.no/2012/04/19/best-practice-for-dealing-with-oauth-2-0-token-expiration-at-the-consumer/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Best-Practice for dealing with OAuth 2.0 Token expiration at the Consumer&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;options&#34;&gt;Options
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Automatically log out each user after being logged in for the token expiry time.&lt;/li&gt;
&lt;li&gt;Extend the token expiration time to the maximum amount of time a user can be logged in.&lt;/li&gt;
&lt;li&gt;Add support for refresh tokens (RTs) that can keep working until a user&amp;rsquo;s login session expires.&lt;/li&gt;
&lt;li&gt;Have the token server issue tokens that don&amp;rsquo;t expire.&lt;/li&gt;
&lt;li&gt;Some combination of the above.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;real-world-solutions&#34;&gt;Real-World Solutions
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.facebook.com/docs/facebook-login/access-tokens&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Facebook: Access Tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.linkedin.com/documents/handling-errors-invalid-tokens&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;LinkedIn: Handling Errors &amp;amp; Invalid Tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://web.archive.org/web/20231002003854/https://developers.blog.box.com/2013/11/13/oauth2-update-longer-lived-refresh-tokens/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Box: OAuth2 update - Longer lived refresh tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.salesforce.com/articleView?id=remoteaccess_oauth_refresh_token_flow.htm&amp;amp;type=5&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Salesforce: Understanding the OAuth Refresh Token Process&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;helpful-drupal-modules&#34;&gt;Helpful Drupal Modules
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/session_expire&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Session expire&lt;/a&gt; (also explains the default login session length)&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/autologout&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Automated Logout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/ejectorseat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ejector Seat&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;similar-modules&#34;&gt;Similar Modules
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/oauth2_login&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OAuth2 Login&lt;/a&gt; redirects users to another Drupal site for authentication, and then sends them back logged in once they&amp;rsquo;re authenticated. This module doesn&amp;rsquo;t do any redirection; everything is done behind the scenes. Users logging in won&amp;rsquo;t even know that they&amp;rsquo;re authenticating against another system. They simply log in using the normal Drupal login process, but get an access token on top of that (if granted). Users that don&amp;rsquo;t exist locally will be created during the login process.&lt;/p&gt;
&lt;p&gt;In conclusion, although this solution isn&amp;rsquo;t the most appropriate given the technology that&amp;rsquo;s now available, it does fit a lot of real-world use cases. At the time of this writing, there are &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/usage/oauth2_authentication&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;130 sites&lt;/a&gt; using it. This is quite impressive given that I recommend against it on the project page!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Responding to Drupal&#39;s Highly Critical SQL Injection Vulnerability</title>
        <link>https://colan.pro/blog/responding-drupals-highly-critical-sql-injection-vulnerability/</link>
        <pubDate>Thu, 03 Sep 2015 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/responding-drupals-highly-critical-sql-injection-vulnerability/</guid>
        <description>&lt;img src="https://colan.pro/blog/responding-drupals-highly-critical-sql-injection-vulnerability/DALL%C2%B7E%202024-06-25%2008.02.21%20-%20A%20vibrant,%20wide%20banner%20image%20representing%20a%20response%20to%20a%20critical%20security%20vulnerability%20in%20Drupal,%20featuring%20elements%20like%20warning%20symbols,%20a%20lock,%20.webp" alt="Featured image of post Responding to Drupal&#39;s Highly Critical SQL Injection Vulnerability" /&gt;&lt;p&gt;On October 15th, 2014, the highly critical &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/SA-CORE-2014-005&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SA-CORE-2014-005 - Drupal core - SQL injection&lt;/a&gt; vulnerability was announced. Shortly afterwards, research showed that sites not patched that same day could very well be compromised. Two weeks later, a &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/PSA-2014-003&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;public service announcement&lt;/a&gt; was released explaining the gravity of the situation. There was also a &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/drupalsa05FAQ&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FAQ&lt;/a&gt;, a &lt;a class=&#34;link&#34; href=&#34;http://www.js.geek.nz/blog/your-drupal-website-has-backdoor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;flowchart&lt;/a&gt; for dealing with it and a &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/drupalgeddon&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;module&lt;/a&gt; that could potentially confirm a compromised site. Needless to say, it was a challenging time for the community.&lt;/p&gt;
&lt;p&gt;At the time, I was asked by a client of mine to analyze a site to determine risk.&lt;/p&gt;
&lt;p&gt;Some common attack vectors associated with the vulnerability were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changing the superuser&amp;rsquo;s (user ID 1) username, password or e-mail address.&lt;/li&gt;
&lt;li&gt;Adding new users to the user table with the administrator role (usually ID 3).&lt;/li&gt;
&lt;li&gt;Adding entries to the menu_router table.&lt;/li&gt;
&lt;li&gt;Adding PHP files to the code base or in the sites/all/files directory.&lt;/li&gt;
&lt;li&gt;Adding nodes (pages) or blocks with executable PHP.&lt;/li&gt;
&lt;li&gt;Downloading the list of user passwords&lt;/li&gt;
&lt;li&gt;Determining hackability through the version listed in CHANGELOG.txt&lt;/li&gt;
&lt;li&gt;Spawned processes run by the Web server&lt;/li&gt;
&lt;li&gt;Adding new roles&lt;/li&gt;
&lt;li&gt;Permission changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So based on the above, and some other sources, it was possible to produce a list of things one could look for to determine if a site had been compromised. As has been discussed elsewhere, failure to confirm any of these did not mean the site was not compromised, but it did provide some indication of risk.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rerun the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/security_review&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Security Review&lt;/a&gt; module.&lt;/li&gt;
&lt;li&gt;Perform checks with the &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/Drupalgeddon&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupalgeddon&lt;/a&gt; &amp;amp; &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/project/site_audit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Site Audit&lt;/a&gt; modules.&lt;/li&gt;
&lt;li&gt;Check for changes to user 1&amp;rsquo;s username, password or e-mail address.&lt;/li&gt;
&lt;li&gt;Check all users in roles other than &amp;ldquo;anonymous&amp;rdquo; and &amp;ldquo;authenticated&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Check for strange entries in the menu_router table.&lt;/li&gt;
&lt;li&gt;Check for code files outside of version control.&lt;/li&gt;
&lt;li&gt;Check for code files inside sites/all/files.&lt;/li&gt;
&lt;li&gt;Check for new nodes or blocks in the DB.&lt;/li&gt;
&lt;li&gt;Check for strange processes spawned by the Web server user.&lt;/li&gt;
&lt;li&gt;Check for any new roles.&lt;/li&gt;
&lt;li&gt;Check for any permission changes.&lt;/li&gt;
&lt;li&gt;Check the mail logs for anything suspicious being sent out.&lt;/li&gt;
&lt;li&gt;Scan site with the &lt;a class=&#34;link&#34; href=&#34;http://sucuri.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Sucuri&lt;/a&gt; tools &lt;a class=&#34;link&#34; href=&#34;http://sitecheck.sucuri.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Free Website Malware and Security Scanner&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;http://www.unmaskparasites.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Unmask Parasites&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are some worthwhile things to note with respect to the checklist above:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Some of the clues (such as 5 and 6 above) would have been long gone as they&amp;rsquo;re rebuilt during cache clears and deployments.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s theoretically possible that malicious processes could have been spawned by the Web servers. The names could have been renamed to look non-malicious, but unless something was set up to make these persist across power cycles, they would be wiped on a system reboot.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s also theoretically possible that user passwords could have been compromised. In Drupal 7, hashed passwords are &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Salt_%28cryptography%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;salted&lt;/a&gt;, but the random string used for the salt could have been read as it&amp;rsquo;s in sites/colan.consulting/settings.php. With that in mind, the site would be susceptible to brute force, &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Dictionary_attack&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;dictionary&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Rainbow_table&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;rainbow table&lt;/a&gt; attacks. If the site isn&amp;rsquo;t going to be rebuilt, it would be a good idea to expire all passwords and forcing users to reset them. If another system is handling authentication, this isn&amp;rsquo;t an issue.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And of course there could be any number of other things. The best course of action would be to rebuild the site. If that&amp;rsquo;s a challenge, always consider the level of risk before deciding not to. Hopefully we won&amp;rsquo;t have to make too many of these determinations in the future.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.acquia.com/blog/shields&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Shields Up!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.acquia.com/blog/learning-hackers-week-after-drupal-sql-injection-announcement&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Learning from hackers a week after the Drupal SQL Injection announcement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://blog.sucuri.net/2014/10/drupal-sql-injection-attempts-in-the-wild.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal SQL Injection Attempts in the Wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.volexity.com/blog/?p=83&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal Vulnerability: Mass Scans &amp;amp; Targeted Exploitation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://www.doit.wisc.edu/news/new-vulnerability-drupal-project-psa/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;UPDATE: New vulnerability–Drupal Project PSA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.getpantheon.com/blog/what-we-are-seeing-drupal-sa-2014-005&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;What We Are Seeing With Drupal SA 2014-005&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://drupal.stackexchange.com/questions/133996/drupal-sa-core-2014-005-how-to-tell-if-my-server-sites-were-compromised&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal SA-CORE-2014-005 - How to tell if my server / sites were compromised?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/drupalsa05FAQ&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FAQ on SA-CORE-2014-005&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/2368709&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;How to improve security on Drupal websites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://stratusclear.com/drupal-sql-injection-attempts-in-the-wild/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal SQL Injection Attempts in the Wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;http://stratusclear.com/drupal-warns-every-drupal-7-website-was-compromised-unless-patched/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal Warns – Every Drupal 7 Website was Compromised Unless Patched&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Drupal Helpers: Tools for DevOps and Deployment</title>
        <link>https://colan.pro/blog/drupal-helpers-tools-devops-and-deployment/</link>
        <pubDate>Mon, 10 Aug 2015 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/blog/drupal-helpers-tools-devops-and-deployment/</guid>
        <description>&lt;img src="https://colan.pro/blog/drupal-helpers-tools-devops-and-deployment/DALL%C2%B7E%202024-06-24%2016.44.07%20-%20A%20vibrant,%20wide%20banner%20image%20representing%20DevOps%20and%20deployment%20tools%20for%20Drupal,%20featuring%20elements%20like%20servers,%20code,%20automation%20symbols,%20and%20Drupa.webp" alt="Featured image of post Drupal Helpers: Tools for DevOps and Deployment" /&gt;&lt;p&gt;As I&amp;rsquo;ve been architecting Drupal solutions for almost ten years now, I&amp;rsquo;ve accumulated quite a bit of knowledge on &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/DevOps&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;devops&lt;/a&gt; best practices, which constitutes a sizeable amount of the consulting that I do. This includes documentation, configuration management, development processes and deployment processes. In this article, I&amp;rsquo;ll be introducing &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drupal Helpers&lt;/a&gt;, a collection of standard scripts and configurations that I use on all of my client projects (where applicable).&lt;/p&gt;
&lt;p&gt;At the time of the writing, the repository provides support for the following operations and &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Drush&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drush&lt;/a&gt; set-up. Additional tools are always welcome.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#refreshing-a-development-sites-database-and-files&#34; &gt;Refreshing a development site&amp;rsquo;s database and files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#deploying-code-to-a-developmentintegration-site&#34; &gt;Deploying code to a development/integration site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#deploying-code-to-staging-or-production-sites&#34; &gt;Deploying code to staging or production sites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#php-configuration-for-drush&#34; &gt;PHP configuration for Drush&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#default-drush-alias-configuration&#34; &gt;Default Drush alias configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#backing-up-databases&#34; &gt;Backing up databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#rebuilding-a-site-with-its-latest-drush-makefile&#34; &gt;Rebuilding a site with its latest Drush makefile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;#deploying-solr-onto-the-glassfish-application-server&#34; &gt;Deploying Solr onto the GlassFish application server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;refreshing-a-development-sites-database-and-files&#34;&gt;Refreshing a development site&amp;rsquo;s database and files
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/resync-drupal-db-for-dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;resync-drupal-db-for-dev&lt;/a&gt; script essentially deploys the database and files from a staging site (Staging) or production site (Prod) onto a development site, but it also does many other things that should be done as part of that process, devifying it.&lt;/p&gt;
&lt;p&gt;It takes source and destination Drush aliases as arguments and the third one, a list of modules to disable, is optional. Here is the usage example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;resync-drupal-db-for-dev &amp;lt;SOURCE_DRUSH_ALIAS&amp;gt; &amp;lt;DESTINATION_DRUSH_ALIAS&amp;gt; [&amp;lt;MODULES_DISABLE&amp;gt;]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It performs the following tasks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Saves a cache-cleared dump of the destination database (DB) as a backup.&lt;/li&gt;
&lt;li&gt;Overwrites the destination DB with the source&amp;rsquo;s.&lt;/li&gt;
&lt;li&gt;Rebuilds the registry in case PHP file locations have changed.&lt;/li&gt;
&lt;li&gt;Updates the DB schema.&lt;/li&gt;
&lt;li&gt;Reverts all features to the code in Features modules.&lt;/li&gt;
&lt;li&gt;Reverts all views to those defined in code.&lt;/li&gt;
&lt;li&gt;Disables modules that shouldn&amp;rsquo;t be enabled during development.&lt;/li&gt;
&lt;li&gt;Enables modules that are helpful for development.&lt;/li&gt;
&lt;li&gt;Disables CSS and JavaScript caching.&lt;/li&gt;
&lt;li&gt;Sets the &lt;em&gt;files&lt;/em&gt; and temporary directories to standard locations.&lt;/li&gt;
&lt;li&gt;Enables on-screen error reporting.&lt;/li&gt;
&lt;li&gt;Disables user-initiated cron runs. &lt;em&gt;This should really be disabled everywhere for &lt;a class=&#34;link&#34; href=&#34;https://colan.consulting/blog/improving-drupal-7-performance-after-period-inactivity&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;performance reasons&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Clears all caches.&lt;/li&gt;
&lt;li&gt;Overwrites the destination&amp;rsquo;s &lt;em&gt;files&lt;/em&gt; directory with the source&amp;rsquo;s.&lt;/li&gt;
&lt;li&gt;Runs cron.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Developers should be doing all of this every time they refresh their DBs. Because it&amp;rsquo;s tricky and time-consuming to do all of these manually, some of the steps are often missed. This leads to configuration mismanagement issues between development sandboxes and other environments. I&amp;rsquo;d recommend that this script, or another one like it, be run frequently on the authoritative development/integration site (Dev) and local development sites to prevent such mishaps.&lt;/p&gt;
&lt;p&gt;The script tries to be as versatile as possible, working in a variety of GNU/Linux environments. If it doesn&amp;rsquo;t work for yours, please submit a merge request so that we can get support added.&lt;/p&gt;
&lt;h2 id=&#34;deploying-code-to-a-developmentintegration-site&#34;&gt;Deploying code to a development/integration site
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/deploy-drupal-code-dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;deploy-drupal-code-dev&lt;/a&gt; script is useful for deploying the latest development code that&amp;rsquo;s been merged to the development branch to Dev. As part of that process, it does everything else that&amp;rsquo;s necessary after a code deployment, including clearing external Varnish caches. It doesn&amp;rsquo;t produce output to the screen when running it directly, as it&amp;rsquo;s assumed to be run as a cron job. All output gets redirected to a log file. A best practice is to have it run nightly so that Dev is kept up-to-date.&lt;/p&gt;
&lt;h2 id=&#34;deploying-code-to-staging-or-production-sites&#34;&gt;Deploying code to staging or production sites
&lt;/h2&gt;&lt;p&gt;The two (2) scripts &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/deploy-drupal-code-qa&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;deploy-drupal-code-qa&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/deploy-drupal-code-prod&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;deploy-drupal-code-prod&lt;/a&gt; basically follow the same idea as the Dev script above, except that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They require a Git release tag as an argument, as only tagged releases should be deployed to Staging and Prod.&lt;/li&gt;
&lt;li&gt;They produce output directly to the screen, as they are intended to be run manually.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;php-configuration-for-drush&#34;&gt;PHP configuration for Drush
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/drush/drush.ini&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;drush.ini&lt;/a&gt; configuration file (see &lt;a class=&#34;link&#34; href=&#34;http://www.drush.org/en/master/configure/#configuring-phpini&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Configuring php.ini&lt;/a&gt; for details) adds Drush-specific configuration to PHP, differentiated by its being run from the command line; Drush&amp;rsquo;s PHP doesn&amp;rsquo;t go through a Web server.&lt;/p&gt;
&lt;p&gt;As Drush is often called upon for batch processing, it requires more resources than Web-server PHP. Also, there aren&amp;rsquo;t usually multiple instances of it running so we don&amp;rsquo;t need be as concerned about overflowing resource limits. With Web servers, there could be a huge number of PHP processes running on public-facing sites.&lt;/p&gt;
&lt;p&gt;The configuration file does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Increases the memory limit.&lt;/li&gt;
&lt;li&gt;Ensures all errors are shown.&lt;/li&gt;
&lt;li&gt;Sets the time zone.&lt;/li&gt;
&lt;li&gt;Increases the maximum execution time. &lt;em&gt;You may need to do this &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/587250#comment-3506436&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;for MySQL/variants as well&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Make sure this is set up by placing the file (or a symlink to it) in your &lt;em&gt;/etc/php5/cli/conf.d/&lt;/em&gt; directory (or the equivalent for different systems).&lt;/p&gt;
&lt;h2 id=&#34;default-drush-alias-configuration&#34;&gt;Default Drush alias configuration
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/drush/default.alias.drushrc.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;default.alias.drushrc.php&lt;/a&gt; Drush alias file is a standard location for storing all common Drush configuration. It needs to be set in each of your site alias&amp;rsquo; configuration stanzas to use it.&lt;/p&gt;
&lt;p&gt;The line is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;?php$aliases[&amp;#39;dev&amp;#39;] = array(  &amp;#39;parent&amp;#39; =&amp;gt; &amp;#39;@default&amp;#39;,  ...?&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It could actually use an update now that &lt;a class=&#34;link&#34; href=&#34;https://www.drupal.org/node/698264&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Better handling of structure-tables and skip-tables options (including cache_* support!)&lt;/a&gt; is done. We no longer need to explicitly state which cache tables we need to skip during certain operations.&lt;/p&gt;
&lt;h2 id=&#34;backing-up-databases&#34;&gt;Backing up databases
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/backup-drupal-db&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;backup-drupal-db&lt;/a&gt; script will back up a Drupal DB whenever it&amp;rsquo;s run. It can be run stand-alone or as a Cron job. To save storage space, cache tables will not be included in the compressed dump files. Each is timestamped, and the &amp;ldquo;LATEST&amp;rdquo; file will always be a symbolic link to the most recent backup. Old backups are automatically deleted after a set number of days; the default is 60 (~2 months).&lt;/p&gt;
&lt;h2 id=&#34;rebuilding-a-site-with-its-latest-drush-makefile&#34;&gt;Rebuilding a site with its latest Drush makefile
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/drupal-remake&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;drupal-remake&lt;/a&gt; script will rebuild a Drupal site&amp;rsquo;s document root to reflect recent changes in its &lt;a class=&#34;link&#34; href=&#34;http://www.drush.org/en/master/make/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drush makefile&lt;/a&gt;. It performs the following tasks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Takes the site off-line.&lt;/li&gt;
&lt;li&gt;Backs up the existing database.&lt;/li&gt;
&lt;li&gt;Updates the Git repository with the latest code.&lt;/li&gt;
&lt;li&gt;Purges the old code base.&lt;/li&gt;
&lt;li&gt;Rebuilds it.&lt;/li&gt;
&lt;li&gt;Re-installs the previous &lt;em&gt;sites&lt;/em&gt; directory (with site-specific configuration).&lt;/li&gt;
&lt;li&gt;Properly sets all file permissions.&lt;/li&gt;
&lt;li&gt;Updates the DB schema.&lt;/li&gt;
&lt;li&gt;Turns the site back on-line.&lt;/li&gt;
&lt;li&gt;Clears all caches.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;deploying-solr-onto-the-glassfish-application-server&#34;&gt;Deploying Solr onto the GlassFish application server
&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://gitlab.com/colan/drupal-helpers/blob/master/scripts/deploy-solr-on-glassfish&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;deploy-solr-on-glassfish&lt;/a&gt; script sets up the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Apache_Solr&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Solr&lt;/a&gt; search engine to run on the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/GlassFish&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GlassFish&lt;/a&gt; application server.&lt;/p&gt;
&lt;p&gt;With Solr 5, it&amp;rsquo;s no longer necessary to run the search engine in an application server. It can run as a stand-alone application. See &lt;a class=&#34;link&#34; href=&#34;http://flink.com.au/install-apache-solr-5-and-drupal-search-api-on-laptop-in-minutes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Install Apache Solr 5 and Drupal Search API on your laptop in minutes&lt;/a&gt; for an example of how to do this. For earlier versions though, this is helpful in getting the Java stack set up to run alongside the PHP one.&lt;/p&gt;
&lt;p&gt;A special thanks goes out to &lt;a class=&#34;link&#34; href=&#34;https://github.com/jamonation&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Jamon Camisso&lt;/a&gt; for &lt;a class=&#34;link&#34; href=&#34;https://gist.github.com/jamonation/38d8adad26344e0a4453&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;posting the original version of this on GitHub&lt;/a&gt; earlier.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Contact</title>
        <link>https://colan.pro/contact/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/contact/</guid>
        <description>&lt;p&gt;To reach me, simply send an e-mail to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;mailto:colan.relive907@passmail.net&#34; &gt;colan.relive907@passmail.net&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clicking on the link should start composing a new message in your mail client.  If not, cut and paste into a new message yourself.&lt;/p&gt;
&lt;p&gt;Contact forms are normally used to hide e-mail addresses from spam harvesters, but I&amp;rsquo;m using an e-mail aliasing service called &lt;a class=&#34;link&#34; href=&#34;https://simplelogin.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SimpleLogin&lt;/a&gt; (via &lt;a class=&#34;link&#34; href=&#34;https://proton.me/blog/proton-and-simplelogin-join-forces&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Proton Mail&lt;/a&gt;).  I can block senders or disable the alias altogether, and then generate a new one whenever this particular address gets overly misused.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Links</title>
        <link>https://colan.pro/links/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/links/</guid>
        <description></description>
        </item>
        <item>
        <title>Search</title>
        <link>https://colan.pro/search/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://colan.pro/search/</guid>
        <description></description>
        </item>
        
    </channel>
</rss>
