<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Community</title><link>https://www.pulumi.com/blog/category/community/</link><description>Pulumi blog posts: Community.</description><language>en-us</language><pubDate>Wed, 01 Apr 2026 00:00:00 -0700</pubDate><item><title>KubeCon EU 2026 Recap: The Year AI Moved Into Production on Kubernetes</title><link>https://www.pulumi.com/blog/kubecon-eu-2026-recap/</link><pubDate>Wed, 01 Apr 2026 00:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/kubecon-eu-2026-recap/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/kubecon-eu-2026-recap/index.png" /&gt;
&lt;p&gt;Amsterdam in late March still has that sharp North Sea wind, but inside the RAI Convention Centre, 13,350 people generated enough energy to heat the building twice over. &lt;a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe-2026/"&gt;KubeCon + CloudNativeCon EU 2026&lt;/a&gt; was the biggest European edition yet, and the shift from previous years was impossible to miss. AI dominated the conference.&lt;/p&gt;
&lt;p&gt;I spent most of the conference at the Pulumi booth, and that turned out to be the best vantage point. Hundreds of visitors stopped by over four days, and I kept asking the same question: what are you actually running in production with AI on Kubernetes? The answers shaped this post more than any keynote did. Almost everyone had a proof of concept. Almost nobody had a production story they were happy with.&lt;/p&gt;
&lt;p&gt;&lt;img src="pulumi-booth.jpg" alt="The Pulumi crew at our booth at KubeCon EU 2026 in Amsterdam"&gt;&lt;/p&gt;
&lt;p&gt;Here is the stat that framed the entire conference for me: &lt;a href="https://www.cncf.io/reports/the-cncf-annual-cloud-native-survey/"&gt;66% of organizations use Kubernetes to host generative AI workloads, but only 7% deploy to production daily&lt;/a&gt;. That gap between experimentation and actual production use matched what I was hearing at the booth. The CNCF&amp;rsquo;s own survey now counts &lt;a href="https://www.cncf.io/reports/state-of-cloud-native-development-q1-2026/"&gt;19.9 million cloud native developers worldwide, 7.3 million of them building AI workloads&lt;/a&gt;. The tooling and the infrastructure need to catch up.&lt;/p&gt;
&lt;p&gt;My takeaway after four days on the ground: lots of working demos, very few production setups people trust. Teams are trying to scale inference, put guardrails around agents, and make GPU infrastructure behave like anything else they run.&lt;/p&gt;
&lt;p&gt;Here is what I saw.&lt;/p&gt;
&lt;h2 id="from-training-to-inference-the-big-pivot"&gt;From training to inference: the big pivot&lt;/h2&gt;
&lt;p&gt;About &lt;a href="https://www.deloitte.com/us/en/insights/industry/technology/technology-media-and-telecom-predictions/2026/compute-power-ai.html"&gt;67% of AI compute now goes to inference&lt;/a&gt;, not training. The inference market is projected to hit &lt;a href="https://www.marketsandmarkets.com/Market-Reports/ai-inference-market-189921964.html"&gt;$255 billion by 2030&lt;/a&gt;. It&amp;rsquo;s also where most of the operational complexity lives.&lt;/p&gt;
&lt;p&gt;NVIDIA leaned into this hard. Their open-source stack around &lt;a href="https://github.com/NVIDIA-NeMo/NeMo"&gt;NeMo&lt;/a&gt; and &lt;a href="https://github.com/ai-dynamo/dynamo"&gt;Dynamo&lt;/a&gt; got significant stage time, but the bigger move was donating three projects to the CNCF: the &lt;a href="https://github.com/NVIDIA/k8s-dra-driver-gpu"&gt;DRA driver&lt;/a&gt; for fractional GPU allocation, the &lt;a href="https://github.com/kai-scheduler/KAI-Scheduler"&gt;KAI Scheduler&lt;/a&gt; for GPU-aware scheduling, and &lt;a href="https://github.com/ai-dynamo/grove"&gt;Grove&lt;/a&gt;. Moving these to community governance signals that GPU infra is becoming part of the standard Kubernetes toolkit.&lt;/p&gt;
&lt;h2 id="the-cncf-donations-that-will-reshape-ai-on-kubernetes"&gt;The CNCF donations that will reshape AI on Kubernetes&lt;/h2&gt;
&lt;p&gt;Every KubeCon has its crop of new CNCF projects, but this year&amp;rsquo;s batch felt different. We are starting to see the building blocks of an AI runtime for Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/llm-d/llm-d"&gt;&lt;strong&gt;llm-d&lt;/strong&gt;&lt;/a&gt; was the headline donation. Created by IBM Research, Red Hat, and Google Cloud, it splits inference workloads by separating prefill and decode phases across different pods. The collaborator list reads like an industry consortium: NVIDIA, CoreWeave, AMD, Cisco, Hugging Face, Intel, Lambda, Mistral AI, UC Berkeley, and UChicago. When that many organizations agree on a single approach to distributed inference, pay attention.&lt;/p&gt;
&lt;p&gt;NVIDIA&amp;rsquo;s &lt;a href="https://github.com/NVIDIA/k8s-dra-driver-gpu"&gt;&lt;strong&gt;DRA driver&lt;/strong&gt;&lt;/a&gt; enables fractional GPU allocation and multi-node NVLink support. GPU multi-tenancy is one of the hardest unsolved problems in Kubernetes right now. Scheduling, isolation, cost attribution — all of it breaks down when multiple workloads share a GPU. The DRA driver does not solve everything, but it gives the community a real starting point.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/kai-scheduler/KAI-Scheduler"&gt;&lt;strong&gt;KAI Scheduler&lt;/strong&gt;&lt;/a&gt; entered the CNCF Sandbox for GPU-aware scheduling. If llm-d handles the inference runtime and the DRA driver handles allocation, KAI Scheduler handles placement. Together, these three projects form the skeleton of a GPU-native Kubernetes stack.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/vmware-tanzu/velero"&gt;&lt;strong&gt;Velero&lt;/strong&gt;&lt;/a&gt;, donated by Broadcom, moved into CNCF Sandbox for backup and restore. AI workloads are stateful now (model weights, checkpoints, fine-tuning data), and backup is no longer optional. Good timing.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/kaito-project/airunway"&gt;&lt;strong&gt;Microsoft AI Runway&lt;/strong&gt;&lt;/a&gt; is an open-source Kubernetes API for inference that plugs in Hugging Face model discovery, GPU memory fit calculations, and cost estimates. Think of it as a model-aware control plane. &lt;a href="https://github.com/HolmesGPT/holmesgpt"&gt;&lt;strong&gt;HolmesGPT&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://github.com/project-dalec/dalec"&gt;&lt;strong&gt;Dalec&lt;/strong&gt;&lt;/a&gt;, also from Microsoft, entered CNCF Sandbox for AI-powered troubleshooting and dependency analysis.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Kubernetes AI Conformance Program&lt;/strong&gt; is growing fast, with certifications nearly doubled and three new requirements proposed for Kubernetes 1.36. Conformance programs are boring until they are not. This one will determine which distributions can credibly claim AI readiness.&lt;/p&gt;
&lt;h2 id="agentic-ai-gets-an-identity-layer"&gt;Agentic AI gets an identity layer&lt;/h2&gt;
&lt;p&gt;If inference was this year&amp;rsquo;s production story, agentic AI was the architecture story. Agents are proliferating, and nobody has quite figured out how to manage and secure them inside Kubernetes yet.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/kagent-dev/kagent"&gt;&lt;strong&gt;kagent&lt;/strong&gt;&lt;/a&gt;, donated to CNCF Sandbox by Solo.io, defines agents as Kubernetes CRDs. It ships with pre-built &lt;a href="https://github.com/modelcontextprotocol/modelcontextprotocol"&gt;MCP&lt;/a&gt; (Model Context Protocol) servers for Kubernetes, Istio, Helm, Argo, Prometheus, Grafana, and Cilium. An agent becomes a first-class Kubernetes resource, schedulable and observable and subject to RBAC, instead of a rogue process running in someone&amp;rsquo;s notebook.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/kagenti/kagenti"&gt;&lt;strong&gt;kagenti&lt;/strong&gt;&lt;/a&gt; from IBM goes after the identity problem directly. Using &lt;a href="https://github.com/spiffe/spire"&gt;SPIFFE/SPIRE&lt;/a&gt;, it gives agents cryptographic identities. When an agent calls an API, you can verify exactly which agent made the call, what trust domain it belongs to, and whether it is authorized. This kind of security work needs to happen before agents proliferate across production clusters. Retrofitting identity later is ugly.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/dapr/dapr-agents"&gt;&lt;strong&gt;Dapr Agents&lt;/strong&gt;&lt;/a&gt; took a different angle with the actor model and durable execution. Each agent gets reliable state management and exactly-once messaging semantics. If your workflows cannot tolerate lost messages or duplicate actions, this matters.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/agentregistry-dev/agentregistry"&gt;&lt;strong&gt;agentregistry&lt;/strong&gt;&lt;/a&gt; showed up as a centralized discovery service for MCP servers and agents. As agents and tool servers multiply, you need a registry to find and manage them, the same way container registries became necessary for images.&lt;/p&gt;
&lt;p&gt;David Soria Parra from Anthropic gave a talk on &lt;a href="https://blog.modelcontextprotocol.io/posts/2026-mcp-roadmap/"&gt;MCP evolving beyond simple tool-calling&lt;/a&gt; into richer interaction patterns (&lt;a href="https://colocatedeventseu2026.sched.com/event/2E7Db/agentics-day-mcp-+-agents-mcp-in-2026-context-is-all-you-need-david-soria-parra-anthropic"&gt;sched&lt;/a&gt;). Google announced the &lt;a href="https://github.com/kubernetes-sigs/agent-sandbox"&gt;&lt;strong&gt;Kubernetes Agent Sandbox&lt;/strong&gt;&lt;/a&gt; for running agentic AI workloads in secure, isolated environments.&lt;/p&gt;
&lt;h2 id="ai-gateways-and-inference-routing"&gt;AI gateways and inference routing&lt;/h2&gt;
&lt;p&gt;Gateway infrastructure had its own mini-conference within KubeCon. The &lt;a href="https://github.com/kubernetes-sigs/gateway-api-inference-extension"&gt;Gateway API Inference Extension&lt;/a&gt; from the Kubernetes SIG introduces model-aware routing and load balancing at the gateway level. Instead of routing by URL path, your gateway routes by model name, version, and capacity. That changes how inference traffic flows through a cluster in a fundamental way.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/envoyproxy/ai-gateway"&gt;&lt;strong&gt;Envoy AI Gateway&lt;/strong&gt;&lt;/a&gt; builds on &lt;a href="https://github.com/envoyproxy/envoy"&gt;Envoy&lt;/a&gt;&amp;rsquo;s existing proxy capabilities with token-aware rate limiting and provider failover. If your primary inference provider is saturated, traffic shifts to a secondary automatically. Rate limiting by token count rather than request count makes much more sense for LLM workloads, where a single request can consume vastly different amounts of compute.&lt;/p&gt;
&lt;p&gt;I want to call out &lt;a href="https://github.com/agentgateway/agentgateway"&gt;&lt;strong&gt;Agentgateway&lt;/strong&gt;&lt;/a&gt; specifically. Written in Rust, it proxies LLM traffic, MCP connections, and agent-to-agent communication, with &lt;a href="https://github.com/cedar-policy/cedar"&gt;Cedar&lt;/a&gt; and &lt;a href="https://github.com/google/cel-spec"&gt;CEL&lt;/a&gt; policy engines for fine-grained access control. Rust&amp;rsquo;s performance characteristics matter here because inference gateway latency adds directly to user-perceived response time.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Kuadrant/kuadrant-operator"&gt;&lt;strong&gt;Kuadrant&lt;/strong&gt;&lt;/a&gt;, now in CNCF Sandbox, layers policy on top of gateway infrastructure and includes MCP server aggregation. Gateways are evolving from dumb traffic proxies into intelligent control planes for AI workloads, and these four projects are driving that shift.&lt;/p&gt;
&lt;h2 id="platform-engineering-absorbs-llmops"&gt;Platform engineering absorbs LLMOps&lt;/h2&gt;
&lt;p&gt;The observability and platform engineering vendors showed up in force. The message was consistent: LLMOps is just platform engineering with new requirements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chronosphere&lt;/strong&gt; demonstrated parallel AI investigation, with multiple agents analyzing different aspects of an incident simultaneously and combining their findings. &lt;strong&gt;SUSE Liz&lt;/strong&gt; takes a domain-specialized approach, deploying different AI agents for different operational domains rather than one general-purpose assistant. &lt;strong&gt;groundcover&lt;/strong&gt; combines eBPF with &lt;a href="https://opentelemetry.io/"&gt;OpenTelemetry&lt;/a&gt; to give coding agents rich runtime context about the systems they are modifying. That last one is subtle but important: if an AI agent is writing code that touches a service, it should understand that service&amp;rsquo;s actual runtime behavior, not just its source code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dynatrace&lt;/strong&gt; and &lt;strong&gt;DevCycle&lt;/strong&gt; partnered to make feature flags observable primitives via &lt;a href="https://github.com/open-feature/spec"&gt;OpenFeature&lt;/a&gt;. Rolling out AI features behind feature flags is table stakes, but having those flags show up in your observability pipeline as first-class signals closes a real gap.&lt;/p&gt;
&lt;p&gt;Shadow AI governance emerged as its own theme. &lt;strong&gt;CAST AI&amp;rsquo;s Kimchi&lt;/strong&gt; can route requests across 50+ models while providing centralized visibility into what models are being used, by whom, and at what cost. Every large organization I talked to had some version of the same problem: teams spinning up model endpoints without central oversight, burning through GPU budgets, creating compliance blind spots they did not even know about.&lt;/p&gt;
&lt;p&gt;GPU multi-tenancy remains genuinely unsolved. Scheduling, workload isolation, cost attribution across shared GPUs — all of it breaks down at scale. Multiple talks addressed pieces of this, but nobody had a complete answer.&lt;/p&gt;
&lt;h2 id="sovereignty-shapes-infrastructure-architecture"&gt;Sovereignty shapes infrastructure architecture&lt;/h2&gt;
&lt;p&gt;Regulation came up in almost every conversation. The EU Cyber Resilience Act is driving compliance requirements deep into software supply chains, and every European organization I spoke with is feeling the pressure. Teams are already changing how they build and deploy software.&lt;/p&gt;
&lt;p&gt;Sovereign Kubernetes is a platform architecture requirement now, not something you can defer to next quarter. Organizations need Kubernetes distributions and cloud regions that guarantee data residency, and they need the tooling to enforce those guarantees programmatically. Self-hosted models are proliferating partly because of capability and cost, but data sovereignty is the accelerant. If your data cannot leave a jurisdiction, neither can your model.&lt;/p&gt;
&lt;p&gt;Runtime isolation is expanding beyond containers. Several talks covered KVM-based isolation for AI workloads, which is heavier than containers but necessary when the threat model includes side-channel attacks on shared GPU memory. The sandboxing conversation has gotten more sophisticated since last year.&lt;/p&gt;
&lt;p&gt;These constraints are not uniquely European. Any organization operating across jurisdictions faces similar pressures, and the regulatory direction globally is toward more data sovereignty requirements, not fewer.&lt;/p&gt;
&lt;p&gt;&lt;img src="showroom.jpg" alt="The KubeCon EU 2026 show floor at the RAI Convention Centre in Amsterdam"&gt;&lt;/p&gt;
&lt;h2 id="what-this-means-for-your-team"&gt;What this means for your team&lt;/h2&gt;
&lt;p&gt;Four days in Amsterdam distilled into five things I would act on now:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Treat inference workloads like production services.&lt;/strong&gt; If you are still deploying models with scripts and hope, stop. Inference infrastructure needs the same IaC discipline as any other production system: version-controlled, tested, policy-enforced.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Evaluate the &lt;a href="https://github.com/kubernetes-sigs/gateway-api-inference-extension"&gt;Gateway API Inference Extension&lt;/a&gt; and &lt;a href="https://github.com/llm-d/llm-d"&gt;llm-d&lt;/a&gt;.&lt;/strong&gt; These are not speculative projects. They have broad industry backing and solve real problems around inference routing and distributed serving. Get them into your test environments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Plan agent identity before agents proliferate.&lt;/strong&gt; &lt;a href="https://github.com/spiffe/spire"&gt;SPIFFE/SPIRE&lt;/a&gt; for agent identity is not optional if you are running agents in production. Retrofitting identity onto an existing agent fleet is painful. Start with &lt;a href="https://github.com/kagenti/kagenti"&gt;kagenti&lt;/a&gt; now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Platform teams should own AI infrastructure.&lt;/strong&gt; Shadow AI is already happening in your organization. The platform engineering team needs to provide self-service AI infrastructure with guardrails before ungoverned model endpoints become a security and cost problem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sovereignty and GPU multi-tenancy are universal.&lt;/strong&gt; Even if you are not subject to the EU Cyber Resilience Act today, data residency requirements are spreading globally. GPU multi-tenancy will affect every organization running inference at scale.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Kubernetes spent the past decade proving it could orchestrate containers. The next decade will test whether it can orchestrate intelligence. Based on what I saw in Amsterdam, the community is building the right pieces, but the gap between what exists and what production demands is still wide. That gap is where the interesting work happens.&lt;/p&gt;</description><author>Engin Diri</author><category>kubernetes</category><category>kubecon</category><category>ai</category><category>platform-engineering</category><category>cloud-native</category></item><item><title>Adding PostgreSQL State Backend Support to Pulumi: A Community Contribution Journey</title><link>https://www.pulumi.com/blog/postgres-diy-backend/</link><pubDate>Thu, 19 Jun 2025 14:46:07 +0300</pubDate><guid>https://www.pulumi.com/blog/postgres-diy-backend/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/postgres-diy-backend/index.png" /&gt;
&lt;p&gt;When managing infrastructure as code at scale, reliable state storage is essential. Pulumi Cloud provides a fully managed, secure, and scalable solution out of the box. For teams that choose to build and maintain their own backend, Pulumi now offers support for PostgreSQL as a DIY state storage option—though this requires additional operational overhead and careful consideration around performance, security, and maintenance.&lt;/p&gt;
&lt;h2 id="the-need-for-database-backed-state-storage"&gt;The Need for Database-Backed State Storage&lt;/h2&gt;
&lt;p&gt;Traditional DIY backends in Pulumi have relied on object storage systems like AWS S3, Google Cloud Storage, or Azure Blob Storage. While these work well for many use cases, they have limitations when it comes to handling very large state files, complex locking mechanisms, and transactional guarantees that some enterprise environments require.&lt;/p&gt;
&lt;p&gt;PostgreSQL stood out as an excellent candidate for state storage due to its:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Large object support&lt;/strong&gt;: Ability to handle substantial state files without size constraints&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ACID compliance&lt;/strong&gt;: Robust transactional guarantees for state consistency&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mature ecosystem&lt;/strong&gt;: Well-established tooling and operational practices&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalability options&lt;/strong&gt;: From single instances to complex replication setups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security features&lt;/strong&gt;: Comprehensive authentication and authorization capabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-community-contribution-process"&gt;The Community Contribution Process&lt;/h2&gt;
&lt;p&gt;This feature came to life through &lt;a href="https://github.com/pulumi/pulumi/pull/19581/files"&gt;PR #19581&lt;/a&gt;, which addressed a long-standing community request tracked in &lt;a href="https://github.com/pulumi/pulumi/issues/5632"&gt;issue #5632&lt;/a&gt;. The development process showcased the collaborative nature of open-source development, with multiple rounds of feedback, testing, and refinement.&lt;/p&gt;
&lt;h3 id="key-technical-challenges"&gt;Key Technical Challenges&lt;/h3&gt;
&lt;p&gt;The implementation required several technical considerations:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Integration with Go Cloud Development Kit (CDK)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The PostgreSQL backend needed to integrate seamlessly with Pulumi&amp;rsquo;s existing blob storage abstraction layer. This was achieved by implementing the &lt;code&gt;blob.BucketURLOpener&lt;/code&gt; interface:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// URLHandler is a URL opener for PostgreSQL URLs.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URLHandler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// OpenBucketURL implements blob.BucketURLOpener.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URLHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;OpenBucketURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewPostgresBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2. Database Schema Design&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The implementation uses a simple but effective schema for storing state data:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pulumi_state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JSONB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TIME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ZONE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DEFAULT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;updated_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TIME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ZONE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DEFAULT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This design allows for efficient key-based lookups while leveraging PostgreSQL&amp;rsquo;s native JSON support for flexible state data storage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Cross-Platform Testing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the significant challenges was ensuring the implementation worked across different operating systems and CI environments. The solution involved using &lt;a href="https://golang.testcontainers.org/modules/postgres/"&gt;testcontainers-go&lt;/a&gt; to spin up PostgreSQL instances during testing, with appropriate skip conditions for environments where Docker isn&amp;rsquo;t available:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;skipIfDockerNotAvailable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GOOS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;windows&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GOOS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;darwin&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Skipping test: Docker not available on this platform in CI&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Additional Docker availability checks...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="performance-and-limitations"&gt;Performance and Limitations&lt;/h2&gt;
&lt;h3 id="postgresql-wins-over-a-plain-s3-bucket"&gt;PostgreSQL wins over a plain S3 bucket&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ACID transactions with row-level locking –&lt;/strong&gt; A postgres backend means strong consistency guarantees.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Faster for smaller state files –&lt;/strong&gt; Community benchmarks show improvements on S3 backend speed for smaller state files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Point-in-time restore –&lt;/strong&gt; WAL-based backups allow for easier rollback.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deep observability –&lt;/strong&gt; plug pg-metrics into Grafana/APM for real-time insight.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gaps-youll-still-close-only-with-pulumi-cloud"&gt;Gaps you&amp;rsquo;ll still close only with Pulumi Cloud&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Server-side policy guardrails (CrossGuard) –&lt;/strong&gt; automatically enforced policies on every preview or deploy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always-on drift detection –&lt;/strong&gt; automatic scans catch out-of-band changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Managed Deployments –&lt;/strong&gt; fully managed runners, PR previews, and dependent stack updates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Org-wide RBAC, SSO/SAML, immutable audit logs&lt;/strong&gt; – turnkey for teams and auditors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search &amp;amp; analytics across &lt;em&gt;all&lt;/em&gt; cloud resources (Insights)&lt;/strong&gt; – not just those managed by Pulumi.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise Secrets &amp;amp; Configuration (ESC)&lt;/strong&gt; - encrypted secrets and config with RBAC, versioning and audit trail.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SOC 2, high availability, and painless upgrades&lt;/strong&gt; – Pulumi operates the control plane so you don&amp;rsquo;t have to.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="getting-started"&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Using the PostgreSQL backend is straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Login to your PostgreSQL backend:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi login postgres://pulumi_user:secure_password@localhost:5432/pulumi_state?sslmode&lt;span class="o"&gt;=&lt;/span&gt;require
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use Pulumi normally:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi up
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Your state is now stored in PostgreSQL!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="community-impact"&gt;Community Impact&lt;/h2&gt;
&lt;p&gt;This contribution demonstrates the power of community-driven development in open source projects. It addresses a real need expressed by Pulumi users while maintaining the high quality standards expected from the project.&lt;/p&gt;
&lt;p&gt;The implementation follows Pulumi&amp;rsquo;s architectural patterns and coding standards, making it a seamless addition to the existing codebase. The comprehensive documentation and testing ensure that future maintainers can easily understand and modify the code.&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What&amp;rsquo;s Next?&lt;/h2&gt;
&lt;p&gt;The PostgreSQL backend opens up several possibilities for future enhancements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;High Availability&lt;/strong&gt;: Support for PostgreSQL clustering and replication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance Optimizations&lt;/strong&gt;: Caching strategies and connection pooling&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced Features&lt;/strong&gt;: Custom backup strategies and state analytics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-tenant Support&lt;/strong&gt;: Isolation patterns for multiple teams or environments&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The addition of PostgreSQL state backend support to Pulumi represents more than just a new feature—it&amp;rsquo;s a testament to the collaborative nature of open source development and the power of community contributions. By providing enterprise-grade state storage options while maintaining the simplicity that makes Pulumi great, this feature enables organizations to adopt infrastructure as code with confidence.&lt;/p&gt;
&lt;p&gt;Whether you&amp;rsquo;re running a small startup or managing infrastructure for a large enterprise, having robust, reliable state storage options is crucial. The PostgreSQL backend provides an improved approach to Do-It-Yourself state management.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in contributing to Pulumi or have ideas for new features, the community welcomes your contributions. This PR serves as an excellent example of how community members can make meaningful improvements to the project while learning from experienced maintainers and following established best practices.&lt;/p&gt;</description><author>Matan Baruch</author><category>features</category><category>diy-backend</category><category>postgresql</category><category>state-management</category><category>community</category></item><item><title>Introducing the Pulumi Puluminaries 2.0 Program</title><link>https://www.pulumi.com/blog/puluminaries-program/</link><pubDate>Mon, 10 Feb 2025 12:15:00 -0800</pubDate><guid>https://www.pulumi.com/blog/puluminaries-program/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/puluminaries-program/index.png" /&gt;
&lt;p&gt;We are excited to announce the Pulumi Puluminaries 2.0 Program. This is a fresh and revitalized way to celebrate and support Pulumi’s most passionate community members. Pulumi Puluminaries are individuals who demonstrate leadership in the Pulumi ecosystem by sharing best practices, creating valuable content, and helping fellow practitioners succeed.&lt;/p&gt;
&lt;p&gt;Before we dive into what is new, we want to recognize and applaud the incredible achievements of our existing Pulumi Puluminaries. You can check out the great folks currently making a difference in our community on the &lt;a href="https://www.pulumi.com/community/puluminaries/"&gt;Pulumi Puluminaries page&lt;/a&gt;. Their hard work and dedication have laid a strong foundation for what is next.&lt;/p&gt;
&lt;h4 id="what-is-the-pulumi-puluminaries-20-program"&gt;What is the Pulumi Puluminaries 2.0 Program?&lt;/h4&gt;
&lt;p&gt;The Pulumi Puluminaries 2.0 Program is designed to recognize and empower developers, architects, and technologists who are committed to driving innovation with Pulumi. This program offers exclusive opportunities to collaborate with Pulumi engineers, gain early access to new features, and share insights with the community.&lt;/p&gt;
&lt;p&gt;Similar to how other ambassador programs bring together dedicated advocates around a specific focus, the Pulumi Puluminaries 2.0 Program unites a community of individuals who champion Pulumi’s approach to cloud engineering. Pulumi Puluminaries lead conversations, help new users adopt Pulumi effectively, and showcase best practices and use cases that highlight the power of Infrastructure as Code. They are also key participants in shaping Pulumi’s future by providing feedback to the product team and taking part in special initiatives.&lt;/p&gt;
&lt;h4 id="what-does-it-mean-to-be-a-pulumi-puluminary"&gt;What does it mean to be a Pulumi Puluminary?&lt;/h4&gt;
&lt;p&gt;Pulumi Puluminaries serve as champions of cloud engineering. They help users navigate the complexities of building, deploying, and managing applications with Pulumi. They also promote the benefits of Infrastructure as Code in modern organizations by creating thought leadership content, hosting or co-hosting events, and offering guidance for those just getting started.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Responsibilities for Pulumi Puluminaries:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a Pulumi Puluminary, you will be expected to engage with the community at least once a quarter. Here are some ways you can contribute:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Community Engagement&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Actively share Pulumi-related articles, tutorials, and project stories.&lt;/li&gt;
&lt;li&gt;Present at conferences, meetups, or webinars on topics that highlight Pulumi’s value.&lt;/li&gt;
&lt;li&gt;Mentor new users and help them get started with Pulumi.&lt;/li&gt;
&lt;li&gt;Participate in Pulumi’s community forums, Slack channels, and social media discussions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Thought Leadership&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write blog posts (like &lt;a href="https://www.pulumi.com/blog/author/simen-a-w-olsen/"&gt;Simen A. W. Olsen&lt;/a&gt; did in his latest post &lt;a href="https://www.pulumi.com/blog/your-perfect-infrastructure/"&gt;Your Perfect Infrastructure May Not Be So Perfect&lt;/a&gt; or &lt;a href="https://www.pulumi.com/blog/author/tyler-mulligan/"&gt;Tyler Mulligan&lt;/a&gt;) or create &lt;a href="https://www.youtube.com/playlist?list=PLyy8Vx2ZoWlqxDJjRRhgLGu1_Oct0VVhN"&gt;videos showcasing&lt;/a&gt; innovative ways to use Pulumi.&lt;/li&gt;
&lt;li&gt;Contribute to discussions around best practices and patterns for cloud engineering with Pulumi.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Product Feedback&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Offer beta-testing support and provide product feedback directly to the Pulumi team.&lt;/li&gt;
&lt;li&gt;Participate in early-access programs and help guide product roadmap decisions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="benefits-of-joining-the-program"&gt;Benefits of Joining the Program&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Early Access&lt;/strong&gt;: Get sneak peeks at new Pulumi features and releases before they are publicly announced.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Direct Collaboration&lt;/strong&gt;: Collaborate one-on-one with Pulumi engineers and product managers, influencing future capabilities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recognition and Swag&lt;/strong&gt;: Receive official Pulumi Puluminaries 2.0 digital badges, exclusive swag, and spotlight opportunities on Pulumi’s blog and at events.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Networking and Growth&lt;/strong&gt;: Build relationships with peers in the Pulumi ecosystem, deepen your technical expertise, and grow your professional network.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="how-to-get-involved"&gt;How to Get Involved&lt;/h4&gt;
&lt;p&gt;We are looking for Pulumi enthusiasts who have shown dedication and passion for empowering others in the Pulumi community. Whether you have built cutting-edge projects, delivered insightful conference talks, or helped users overcome technical hurdles, we would love to hear your story.&lt;/p&gt;
&lt;p&gt;Whether you want to apply for yourself or nominate someone else, we’d love to hear from you!&lt;/p&gt;
&lt;a
href="https://docs.google.com/forms/d/e/1FAIpQLScdi58QR5SYDYoXhceFumlrjsVxHOOCgCICNw_t3V3qSK3K6w/viewform"
class="btn btn-outline"
&gt;
Apply or Nominate Now
&lt;/a&gt;</description><author>Engin Diri</author><category>puluminaries</category><category>community</category><category>program</category></item><item><title>Integrating DevOps and Security in Platform Engineering</title><link>https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/</link><pubDate>Wed, 11 Dec 2024 07:41:06 +0000</pubDate><guid>https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/integrating-devops-and-security-for-scalable-platform-engineering/index.png" /&gt;
&lt;p&gt;Platform engineering has become essential for mid-to-large organizations, moving beyond a DevOps trend. Gartner predicts that by 2026, 80% of software companies will have internal platform services to streamline development. The goal is to empower developers with self-service tools while maintaining security, compliance, and reliability through DevSecOps practices.&lt;/p&gt;
&lt;p&gt;At PulumiUP Europe 2024, experts shared insights on aligning DevOps with security to build scalable, secure platforms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jess Mink, Sr. Director of Platform Engineering at Honeycomb&lt;/li&gt;
&lt;li&gt;Kief Morris, Global Head of Infrastructure Engineering at ThoughtWorks&lt;/li&gt;
&lt;li&gt;Lindsay Jack, VP of Engineering &amp;amp; Security at Snyk&lt;/li&gt;
&lt;li&gt;Nariman Aga-Tagiyev, Application Security Architect at WiseFrog Security&lt;/li&gt;
&lt;li&gt;Komal Ali, Engineering Manager at Pulumi&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The panel discussed key strategies, challenges, and pillars of successful platform engineering.&lt;/p&gt;
&lt;h2 id="in-this-article"&gt;In this article:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#the-core-pillars-of-platform-engineering"&gt;The Core Pillars of Platform Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#aligning-devops-and-security-for-secure-platform-engineering"&gt;Aligning DevOps and Security for Secure Platform Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#shift-left-security"&gt;Shift Left Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#embrace-automation-and-standardization"&gt;Embrace Automation and Standardization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#prioritize-observability-and-monitoring"&gt;Prioritize Observability and Monitoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#foster-a-culture-of-collaboration"&gt;Foster a Culture of Collaboration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#challenges-of-integrating-security-in-platform-engineering"&gt;Challenges of Integrating Security in Platform Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#balancing-autonomy-and-control"&gt;Balancing Autonomy and Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#driving-adoption-and-changing-mindsets"&gt;Driving Adoption and Changing Mindsets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#adapting-to-evolving-needs-and-technologies"&gt;Adapting to Evolving Needs and Technologies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#measuring-success-in-secure-platform-engineering"&gt;Measuring Success in Secure Platform Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/integrating-devops-and-security-for-scalable-platform-engineering/#the-future-of-secure-platform-engineering"&gt;The Future of Secure Platform Engineering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-core-pillars-of-platform-engineering"&gt;The Core Pillars of Platform Engineering&lt;/h2&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/WUpyqn1Jfwg?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/blog/the-guide-platform-engineering-idp-steps-best-practices/"&gt;Platform engineering teams&lt;/a&gt; comprise multiple professionals with many responsibilities and focus areas. According to our panel of experts, the core pillars of platform engineering include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/blog/software-developer-experience-devex-devx-devops-culture/"&gt;Developer Experience (DevEx)&lt;/a&gt;&lt;/strong&gt;: Provide developers with the tools, frameworks, and abstractions they need to be productive and proactive without getting stuck in infrastructure or operational concerns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/blog/pulumi-patterns-and-practices/#an-effective-internal-developer-platform"&gt;Reliability and Scalability&lt;/a&gt;&lt;/strong&gt;: Ensure that the platform and infrastructure can support the organization&amp;rsquo;s needs, with the ability to scale up or down as required.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/"&gt;Security and Compliance&lt;/a&gt;&lt;/strong&gt;: Embed robust, accessible security and compliance frameworks into the development lifecycle while making it easy for developers to adhere to these policies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/automation-api/"&gt;Automation and Tooling&lt;/a&gt;&lt;/strong&gt;: Leverage &lt;a href="https://www.pulumi.com/product/infrastructure-as-code/"&gt;Infrastructure as Code (IaC)&lt;/a&gt; and automation to enforce standardized processes and consistency and reduce cognitive load and manual effort.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/product/pulumi-insights/"&gt;Observability and Monitoring&lt;/a&gt;&lt;/strong&gt;: Provide visibility into the platform&amp;rsquo;s health and performance, delivering actionable insights that allow teams to identify and resolve issues quickly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These pillars work together to create a platform that empowers developers to innovate and deliver value to the organization and customers while maintaining the necessary controls and safeguards.&lt;/p&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;As Jess Mink, Director of Platform Engineering at &lt;a href="https://www.pulumi.com/blog/observability-with-infrastructure-as-code/"&gt;Honeycomb&lt;/a&gt;, explains:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;The goal of platform engineering is to help the company run smoother and faster and unlock things people didn&amp;rsquo;t know were possible [&amp;hellip;] We tend to focus on tools and software, but it&amp;rsquo;s really about people, processes, and tools. If you consider this, platforms are responsible for social and technical support across the organization. A common pitfall is building tools no one uses because you didn’t meet people where they are.&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="aligning-devops-and-security-for-secure-platform-engineering"&gt;Aligning DevOps and Security for Secure Platform Engineering&lt;/h2&gt;
&lt;p&gt;Integrating security into platform engineering ensures it becomes a proactive part of the development lifecycle and ensures that &amp;ldquo;&lt;a href="https://www.pulumi.com/blog/devsecops-strategy-security-automation-tivity-health/"&gt;DevSecOps&lt;/a&gt;&amp;rdquo; is not an afterthought but a core consideration.&lt;/p&gt;
&lt;p&gt;Key best practices shared by the panel include:&lt;/p&gt;
&lt;h3 id="shift-left-security"&gt;Shift Left Security&lt;/h3&gt;
&lt;p&gt;One of the fundamental principles of DevSecOps is to &amp;ldquo;shift left&amp;rdquo; - that is, to integrate security earlier in the development process rather than waiting until the end. This can involve activities such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Incorporating security requirements and threat modeling into the initial design phase&lt;/li&gt;
&lt;li&gt;Automating security scans and tests as part of the continuous integration (CI) pipeline&lt;/li&gt;
&lt;li&gt;Providing developers with secure coding guidelines and tools to &lt;a href="https://www.pulumi.com/blog/drift-detection/#why-pulumi-cloud-drift-detection-and-remediation"&gt;identify and remediate vulnerabilities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By addressing security concerns upfront, organizations can reduce the time and cost of remediating issues later in the development lifecycle.&lt;/p&gt;
&lt;h3 id="embrace-automation-and-standardization"&gt;Embrace Automation and Standardization&lt;/h3&gt;
&lt;p&gt;Consistency is key. Platform engineering teams should leverage automation and built-in safeguards and security processes. This may include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automating the provisioning of secure infrastructure and application environments&lt;/li&gt;
&lt;li&gt;Implementing Infrastructure as Code (IaC) to define and &lt;a href="https://www.pulumi.com/blog/pulumi-is-imperative-declarative-imperative/"&gt;manage infrastructure in a declarative&lt;/a&gt;, version-controlled manner&lt;/li&gt;
&lt;li&gt;Standardizing security controls, policies, and configurations across the platform&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By automating these tasks, platform engineering teams can reduce the risk of human error, improve visibility and auditability, and free up developers to focus on building features rather than managing infrastructure.&lt;/p&gt;
&lt;h3 id="prioritize-observability-and-monitoring"&gt;Prioritize Observability and Monitoring&lt;/h3&gt;
&lt;p&gt;Effective security requires visibility into the health and performance of the platform. Platform engineering teams should invest in robust observability and monitoring solutions to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/drift-detection/"&gt;Detect and respond&lt;/a&gt; to security incidents and anomalies in real-time&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/product/pulumi-insights/"&gt;Gain insights&lt;/a&gt; into the behavior and usage patterns of the platform&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/unified-programmatic-approach-infrastructure-management-bmw-using-pulumi/#policy-enforcement-ensuring-compliance-and-security"&gt;Identify and address&lt;/a&gt; vulnerabilities or misconfigurations proactively&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By integrating security-focused monitoring and alerting into the platform, organizations can quickly identify and mitigate threats while also providing developers with the necessary context to understand and address security-related issues.&lt;/p&gt;
&lt;h3 id="foster-a-culture-of-collaboration"&gt;Foster a Culture of Collaboration&lt;/h3&gt;
&lt;p&gt;Platform engineering is often referred to as being the practical application of DevOps practices. Integrating security practices often requires a cultural shift towards collaboration and shared responsibility between all teams in development, operations, and security, thus the name DevSecOps. Platform engineering teams can facilitate this by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Treating &lt;a href="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/#platforms-as-products-driving-success"&gt;Platforms as Products&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Involving security stakeholders in the design and planning of platform initiatives&lt;/li&gt;
&lt;li&gt;Providing security training and education to developers to empower them to make informed decisions&lt;/li&gt;
&lt;li&gt;Establishing communication channels and feedback loops between teams&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;As Kief Morris, Global Head of Infrastructure Engineering at &lt;a href="https://www.thoughtworks.com/en-us"&gt;ThoughtWorks&lt;/a&gt;, explains:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;There is a new way of thinking that is trying to avoid that &amp;ldquo;build it, and they will come mentality,&amp;rdquo; which leads to building it and nobody using it. One of the trends we are seeing is product thinking [&amp;hellip;]—using techniques like creating user personas of different types of users in the organization, conducting research to understand their needs, and talking with them.&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Breaking silos and fostering communication helps organizations build secure, scalable platforms that support the needs of developers, platform engineers, architects, and security teams.&lt;/p&gt;
&lt;h2 id="challenges-of-integrating-security-in-platform-engineering"&gt;Challenges of Integrating Security in Platform Engineering&lt;/h2&gt;
&lt;p&gt;While the benefits of integrating DevOps and security in platform engineering are clear, the journey has expected challenges. Our panel of experts highlighted several key obstacles that organizations may face:&lt;/p&gt;
&lt;h3 id="balancing-autonomy-and-control"&gt;Balancing Autonomy and Control&lt;/h3&gt;
&lt;p&gt;The primary goal is to empower developers to be more productive and proactive. However, this autonomy needs to be balanced with necessary security controls and governance measures.&lt;/p&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;Jess Mink points out the importance of achieving harmony between developer autonomy and operational control, stating:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;It&amp;rsquo;s a delicate balance - you want to make things easy for developers, but you also need to maintain the right level of control and security. It&amp;rsquo;s about finding the right abstractions and interfaces that give developers the freedom they need while still ensuring the platform remains secure and compliant.&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="driving-adoption-and-changing-mindsets"&gt;Driving Adoption and Changing Mindsets&lt;/h3&gt;
&lt;p&gt;Integrating security into the platform engineering workflow can often be met with resistance from developers accustomed to moving quickly and may view security as an obstacle to their productivity.&lt;/p&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;As Nariman, a Software Security Architect, notes:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;The challenge is not just about the tools or the technology - it&amp;rsquo;s about changing the mindset and getting people to understand the importance of security. You need to find ways to motivate developers and make them feel like they&amp;rsquo;re part of the solution rather than just imposing more rules and processes.&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Effective communication, education, and a focus on the business value of security are key to driving adoption and fostering a culture of shared responsibility.&lt;/p&gt;
&lt;h3 id="adapting-to-evolving-needs-and-technologies"&gt;Adapting to Evolving Needs and Technologies&lt;/h3&gt;
&lt;p&gt;As organizations grow and their technology stacks evolve, the demands on the platform engineering team can shift rapidly. Keeping up with these changes, while maintaining a secure and reliable platform, can be a significant challenge.&lt;/p&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;Lindsay Jack, VP of Engineering for the Platform Division at &lt;a href="https://partners.snyk.io/English/solutions/solution/2908/pulumi"&gt;Snyk&lt;/a&gt;, explains:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;You might have a platform team that&amp;rsquo;s really good at a certain set of technologies, but then the organization starts moving in a new direction, and suddenly those skills don&amp;rsquo;t match up anymore. It&amp;rsquo;s about being agile and adaptable and making sure you have the right mix of skills and expertise to support the organization&amp;rsquo;s evolving needs&lt;/em&gt;.&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Fostering internal mobility, continuous learning, and a flexible, modular platform architecture can help platform engineering teams navigate these changes more effectively.&lt;/p&gt;
&lt;h2 id="measuring-success-in-secure-platform-engineering"&gt;Measuring Success in Secure Platform Engineering&lt;/h2&gt;
&lt;p&gt;Measuring the success of a platform engineering initiative can be complex as it involves balancing a range of technical, operational, and business-oriented metrics but also considers human factors. According to our panel, some key metrics to include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Developer Experience&lt;/strong&gt;: Metrics such as developer satisfaction surveys, time-to-onboard new developers, and the number of self-service platform capabilities can provide insights into the effectiveness of the platform in supporting developer productivity and autonomy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reliability and Scalability&lt;/strong&gt;: Monitoring service-level objectives (SLOs), incident response times, and the ability to handle increased traffic or user demands can help assess the platform&amp;rsquo;s reliability and scalability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security and Compliance&lt;/strong&gt;: Tracking the number of security incidents, the ratio of security issues found during threat modeling versus post-deployment, and the adoption of security best practices can indicate the platform&amp;rsquo;s security posture.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automation and Tooling&lt;/strong&gt;: Metrics like the percentage of infrastructure provisioned through code, the frequency of platform updates, and the time saved through automation can demonstrate the platform&amp;rsquo;s operational efficiency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observability and Monitoring&lt;/strong&gt;: Measuring the effectiveness of observability tools, the time to detect and resolve issues, and the quality of incident reports can &lt;a href="https://www.pulumi.com/blog/insights-cloud-account-discovery/"&gt;provide insights into the platform&amp;rsquo;s overall health&lt;/a&gt; and performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="note note-tip"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;As Jess Mink emphasizes, it&amp;rsquo;s important not just to collect these metrics but to use them to drive meaningful action and improvement:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;We look at all of those [metric categories] every quarter and write summaries that go up to the executive level. This creates visibility and a shared understanding of problems so that there&amp;rsquo;s room for movement and change in the right ways.&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="the-future-of-secure-platform-engineering"&gt;The Future of Secure Platform Engineering&lt;/h2&gt;
&lt;p&gt;Software development and infrastructure management are evolving, and the role of platform engineering will only become more critical to support it. By integrating DevOps and security practices, platform engineering teams can create scalable, secure platforms that empower developers to be more productive and innovate, delivering business value.&lt;/p&gt;
&lt;p&gt;Learn how Pulumi customers build secure, scalable platforms and empower their development teams:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tivity Health&lt;/strong&gt;: &lt;a href="https://www.pulumi.com/blog/devsecops-strategy-security-automation-tivity-health/"&gt;DevSecOps Game-Changer: Security Automation That Delivers Business Results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BMW Group&lt;/strong&gt;: &lt;a href="https://www.pulumi.com/blog/unified-programmatic-approach-infrastructure-management-bmw-using-pulumi/"&gt;Unified and Programmatic Approach to Infrastructure Management at BMW Using Pulumi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lemonade&lt;/strong&gt;: &lt;a href="https://www.pulumi.com/case-studies/lemonade/"&gt;How the DevOps team supports a much larger group of developers&lt;/a&gt; using by Pulumi to standardize infrastructure components and enforce best practices.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Discover platform engineering best practices in &lt;a href="https://www.pulumi.com/blog/the-guide-platform-engineering-idp-steps-best-practices/"&gt;The Guide to Platform Engineering: 7 Steps to Get It Right&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Build secure, scalable platforms with confidence—get started with the &lt;a href="https://info.pulumi.com/platform-engineering-workshop-series"&gt;Platform Engineering Workshop Series &amp;amp; Course&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</description><author>Sara Huddleston</author><category>devsecops</category><category>platform-engineering</category><category>developer-experience</category><category>devops</category><category>security</category></item><item><title>PulumiUP 2024: Dive Into the Future of Cloud, Platform Engineering, and AI/ML</title><link>https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/</link><pubDate>Wed, 11 Sep 2024 07:04:40 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/index.png" /&gt;
&lt;p&gt;PulumiUP 2024 is just around the corner! It will be held on September 18th, starting at 8 AM PT | 15:00 UTC +0, and with over 5,500 engineers from all over the world already registered, this is shaping up to be the must-attend event for cloud professionals, platform engineers, and AI/ML enthusiasts alike. From entry-level engineers to tech executives, this event brings together professionals from companies of all sizes to explore the latest innovations and best practices in &lt;strong&gt;Cloud and IaC&lt;/strong&gt;, &lt;strong&gt;Platform Engineering &amp;amp; DevOps&lt;/strong&gt;, and &lt;strong&gt;AI/ML&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you haven’t registered yet, now’s the time! &lt;a href="https://conference.pulumi.com/schedule/?utm_source=PulumiUP&amp;amp;utm_medium=web&amp;amp;utm_campaign=FY2025Q1_Event_PulumiUP"&gt;Start building your schedule today&lt;/a&gt;, select the talks you want to watch live and on-demand and add them to your schedule.&lt;/p&gt;
&lt;h2 id="pulumiup-at-glance"&gt;PulumiUP at Glance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#main-track-keynote-cloud-culture-talks-and-more"&gt;Main Track: Keynote, Cloud Culture Talks, and More&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#aiml-track-highlights"&gt;AI/ML Track Highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#platform-engineering-and-devops-track-highlights"&gt;Platform Engineering and DevOps Track Highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#cloud-and-iac-track-highlights"&gt;Cloud and IaC Track Highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#workshops-and-hands-on-learning"&gt;Workshops and Hands-On Learning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#amazing-partners-and-sponsors"&gt;Amazing Partners and Sponsors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/#build-your-schedule-now"&gt;Build Your Schedule Now&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="main-track-keynote-cloud-culture-talks-and-more"&gt;Main Track: Keynote, Cloud Culture Talks, and More&lt;/h2&gt;
&lt;p&gt;In the Main Track, you’ll hear directly from the Pulumi leadership team about exciting product innovations. Don’t miss the Cloud Culture talks focused on the human side of technology and collaboration.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/events/pulumiup-2024-keynote/"&gt;Keynote and New Product Announcements&lt;/a&gt;&lt;/strong&gt; - Joe Duffy (Co-founder and CEO), Luke Hoban (CTO), and other key Pulumi leaders will unveil new products and innovations shaping the next wave of cloud development. Expect to see live demos showcasing how these tools can revolutionize your workflows, from cloud infrastructure to security automation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/9Xf6DJMvQ08"&gt;Why Care About Building a Cloud Center of Excellence?&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Alex Radu (VP Product &amp;amp; Marketing Manager, Public Cloud, J.P. Morgan) discusses why building a Cloud Center of Excellence is essential for long-term cloud strategy success.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/30wTCwfj3cc"&gt;What Is &amp;lsquo;HugOps&amp;rsquo; and Why Is It Important?&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Rees Pozzi (Senior Platform Engineer, Kainos) explores the meaning and importance of &amp;ldquo;HugOps,&amp;rdquo; a practice promoting empathy and collaboration in the tech world but also by all those impacted by it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="aiml-track-highlights"&gt;AI/ML Track Highlights&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://conference.pulumi.com/talks/panel-ai-cloud-development/"&gt;&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/pulumiup_2024-ai-cloud-development.png"
alt="Panelists of AI for Cloud Development" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Panel: AI for Cloud Development&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AI is transforming how we approach development and infrastructure, and PulumiUP offers an incredible lineup of talks and panels on the topic.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/4IWGNoNVbiM"&gt;Data Privacy Challenges with Large Language Models&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Aditi Godbole (Data Science, AI &amp;amp; ML Leader, SAP) will address the critical question of managing data privacy, addressing LLM basics, AI data privacy fundamentals, and specific privacy issues in LLMs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/CoZM9BCJcJ4"&gt;Pulumi Powered AI/ML on Kubernetes&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Jason Smith (App Modernization Specialist, Google Cloud) will show you how to serve an open-source LLM with a RAG on Kubernetes and set up a Kubernetes environment for AI/ML workloads with Pulumi.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/WoM8Bj76_Fw"&gt;AI Tools for Developers&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Jim Clark (Principal Software Engineer, Docker) will explore how Tools can enhance the capabilities of AI assistants and show how the combination of AI, Tools, and containerized runtimes, can enhance interactions between developers and their tools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/2mlb2jEBkoo"&gt;The AI Governance Challenge&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Patty O&amp;rsquo;Callaghan (Technical Director, Charles River) will explore the complexities of AI governance and how to navigate them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/events/panel-ai-in-cloud-development/"&gt;Panel Discussion: &amp;ldquo;AI for Cloud Development&amp;rdquo;&lt;/a&gt;&lt;/strong&gt; - Luke Hoban (CTO, Pulumi), Phillip Carter (Principal Product Manager, Honeycomb), Giri Sreenivas (CPO, Docker), Clare Liguori (Senior Principal Software Engineer, AWS) and Meagan Cojocar (Principal Product Manager, Pulumi) will provide diverse perspectives on how AI is shaping cloud infrastructure.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="platform-engineering-and-devops-track-highlights"&gt;Platform Engineering and DevOps Track Highlights&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/pulumiup_2024-secrets-policies-automating-cybersecurity.png"
alt="Panelists of Secrets and Policies—Automating Cybersecurity" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Panel: Secrets and Policies—Automating Cybersecurity&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Platform Engineering &amp;amp; DevOps track at PulumiUP is perfect for anyone looking to automate infrastructure, secure their systems, and scale their environments with ease. This track features talks and panels on cutting-edge technologies and practices.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/WZD1z2ldweY"&gt;Moving Mountains: How IaC Unlocks Massive Refactoring Possibilities&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Shaun Verch (Infrastructure Engineer, Oso) will show you how infrastructure as code can transform large-scale refactoring projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/1Q3XPmenthg"&gt;Using Pulumi to Empower Kubernetes Fleet Management&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Blake Romano (Senior Software Engineer, Imagine Learning) will show you how Imagine Learning leverages Pulumi to manage a fleet of Kubernetes clusters and other platform resources quickly and reliably, and how it revolutionized their workflow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/f2r9rS9U2CA"&gt;Streamline Your Infrastructure Deployment with GitOps and Pulumi Operator&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Sam Cogan (Solutions Architect &amp;amp; Azure MVP, WTW) will highlight how you can define your infrastructure in Git, and have Pulumi automatically reconcile it into deployed infrastructure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/EQwpC02CQ9k"&gt;Is This a Platform? Platform Engineering Before PMF&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Jk Jensen (Team Lead, Staff Software Engineer, MystenLabs) will share how they built their service platform around Pulumi to help engineers and researchers move from prototypes to deployed environments, enabling their teams to iterate more quickly and develop an increasing number of systems without additional complexity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/events/security-automation-faster-cheaper-better/"&gt;Security Automation—Faster. Cheaper. Better.&lt;/a&gt;&amp;quot;&lt;/strong&gt; - David Giambruno (VP of Engineering and DevOps, Tivity Health) and Joe Duffy (Founder/CEO, Pulumi) will discuss security automation and how these efforts impacted speed and agility, cost optimization and improved security and compliance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/CGE8VXgkjug"&gt;Meet Devs Where They Are: Why IaC Must Be Real Code&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Jeremy Adams (Head of Ecosystems, Dagger) will present why real code (that teams already use for applications) is essential for both IaC and CI/CD pipelines, and to meet modern DevOps best practices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/2a-wlUnBY1g"&gt;Security of IaC Pipelines and Infrastructure Governance With Policies-As-Code&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Marina Novikova (Senior Partner Solutions Architect, AWS) and Andy Taylor (Senior Networking Specialist/ Solutions Architect, AWS) will explore security best practices for IaC pipelines and infrastructure governance using policies-as-code, cover best practices for handling sensitive information like access keys, tokens and encryption keys, and scaling and automating your DevSecOps.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/events/secrets-policies-automating-cybersecurity/"&gt;Panel Discussion: &amp;ldquo;Secrets and Policies—Automating Cybersecurity&amp;rdquo;&lt;/a&gt;&lt;/strong&gt; - Arun Loganathan (Senior Product Manager, Pulumi), Maya Kaczorowski (PM of Security), Jason Meller (VP, Product, 1Password), and Ofir Cohen (CTO, Container Security, Wiz) will explore the intersection of innovation and security, offering insights into how AI is reshaping the threat landscape and how organizations can stay ahead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cloud-and-iac-track-highlights"&gt;Cloud and IaC Track Highlights&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/pulumiup-global-cloud-iac-platform-engineering-ai-conference/pulumiup_2024-infrastructure-as-code.png"
alt="Panelists of Infrastructure as Code - Can we do better?" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Panel: Infrastructure as Code - Can we do better?&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Cloud and IaC track is ideal for those wanting to deepen their understanding of infrastructure as code and its impact on modern cloud computing. Learn from industry pioneers and see where the future of IaC is headed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/blog/from-cdk-pulumi-evolution-of-sst/"&gt;From CDK to Pulumi: Evolution of SST&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Dax Raad (Founding Engineer, SST) and Jay V (Founder, SST) will share insights into the early development of their product, initially built on AWS Cloud Development Kit (CDK), the challenges they encountered and the groundbreaking decision to transition to Pulumi.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/blog/unified-programmatic-approach-infrastructure-management-bmw-using-pulumi/"&gt;Unified Software Development at BMW Software Factory with Pulumi&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Jan-Peter Alten (Expert Software Engineer, DevOps, BMW Group) will showcase how BMW uses Pulumi to unify their software development processes, resulting in an increase in developer productivity, streamlined infrastructure management, and enhanced scalability, security, and compliance across their complex software ecosystem.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/E077QbXPOZE"&gt;Stacking Accounts: Multi-Account Deployments in a Single Stack for Monitoring, Management, and More&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Denis Willett (Software Engineer, North Carolina Institute for Climate Studies) will explain how they use Pulumi for managing 60+PB of environmental data across AWS, GCP, and Azure and leverage multi-account deployments in a single stack via the Pulumi Automation API.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://youtu.be/C5ZuEVXesOk"&gt;Industrialize the Configuration of Your GitHub Repositories With IaC&lt;/a&gt;&amp;quot;&lt;/strong&gt; - Alexandre Nédélec (Software Engineer, Avanade) will live code using the GitHub, Azure native, and Azure AD Pulumi providers to create a GitHub repository and configure its pipeline to deploy to Azure using OpenID Connect.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/events/panel-infrastructure-as-code-can-we-do-better/"&gt;Panel Discussion: &amp;ldquo;Infrastructure as Code — Can We Do Better?&amp;rdquo;&lt;/a&gt;&lt;/strong&gt; - Joe Duffy (Co-Founder and CEO, Pulumi), Brian Grant (CTO, Stealth), Elad Ben-Israel (Co-Founder and CEO, Winglang), Adam Jacob (Co-Founder and CEO, System Initiative), and Luke Hoban (CTO, Pulumi) will discuss the past, the present, and the future of Infrastructure as Code and the overall infrastructure technologies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="workshops-and-hands-on-learning"&gt;Workshops and Hands-On Learning&lt;/h2&gt;
&lt;p&gt;Want to get hands-on experience? Our live workshops are designed to deepen your understanding of trending topics, Pulumi, and its applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/resources/managing-team-secrets-with-1password-pulumi-esc/"&gt;Managing Team Secrets with 1Password &amp;amp; Pulumi ESC&lt;/a&gt;&amp;quot;&lt;/strong&gt; on September 25, led by Phil Johnston (1Password) and Diana Esteves (Pulumi).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/resources/securing-iac-pipelines-in-regulated-industries/"&gt;Securing IaC Pipelines in Regulated Industries&lt;/a&gt;&amp;quot;&lt;/strong&gt; on September 26, led by Josh Kodroff (Pulumi) and Marina Novikova (AWS).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/resources/deploy-tailscale-infrastructure-with-pulumi/"&gt;Deploy Tailscale infrastructure in AWS with Pulumi&lt;/a&gt;&amp;quot;&lt;/strong&gt; on October 15, led by Diana Esteves (Pulumi) and Lee Briggs (Tailscale).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;&lt;a href="https://www.pulumi.com/resources/observability-as-code-for-ai-apps-new-relic/"&gt;Observability as Code for AI Apps with New Relic and Pulumi&lt;/a&gt;&amp;quot;&lt;/strong&gt; on October 30, led by Diana Esteves (Pulumi) and Harry Kimpel (New Relic).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="amazing-partners-and-sponsors"&gt;Amazing Partners and Sponsors&lt;/h2&gt;
&lt;p&gt;Thank you to our amazing customers, sponsors, and partners for supporting PulumiUP!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aws.amazon.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;AWS&lt;/a&gt;&lt;/strong&gt; The world&amp;rsquo;s most comprehensive and broadly adopted cloud, offering over 200 fully featured services from data centers globally.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://cloud.google.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Google Cloud&lt;/a&gt;&lt;/strong&gt; Help developers build quickly, securely, and cost effectively with the next generation of modern infrastructure designed to meet specific workload and industry needs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://newrelic.com/instant-observability/pulumi/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;New Relic&lt;/a&gt;&lt;/strong&gt; Data for engineers to monitor, debug, and improve their entire stack.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://docker.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Docker&lt;/a&gt;&lt;/strong&gt; Accelerate how you build, share, and run applications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://1password.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;1Password&lt;/a&gt;&lt;/strong&gt; Streamline how you manage SSH keys, API tokens, and other infrastructure secrets throughout the entire software development life cycle.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://tailscale.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Tailscale&lt;/a&gt;&lt;/strong&gt; Make creating software-defined networks easy: securely connecting users, services, and devices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://pinecone.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Pinecone&lt;/a&gt;&lt;/strong&gt; Build remarkable GenAI applications fast, with lower cost, better performance, and greater ease of use at any scale.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://wiz.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Wiz&lt;/a&gt;&lt;/strong&gt; Secure everything you build and run in the cloud.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://honeycomb.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Honeycomb&lt;/a&gt;&lt;/strong&gt; Observability that helps solve problems you couldn’t before.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://mystenlabs.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Mysten Labs&lt;/a&gt;&lt;/strong&gt; Building critical infrastructure to enable a more decentralized internet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://imaginelearning.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Imagine Learning&lt;/a&gt;&lt;/strong&gt; Empowering educators to inspire breakthrough moments in every student’s unique learning journey with digital-first, K–12 education solutions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dagger.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Dagger&lt;/a&gt;&lt;/strong&gt; Powerful, programmable open source CI/CD engine that runs your pipelines in containers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://osohq.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Oso&lt;/a&gt;&lt;/strong&gt; Authorization as a service.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="build-your-schedule-now"&gt;Build Your Schedule Now&lt;/h2&gt;
&lt;p&gt;With so many compelling topics across AI/ML, Platform Engineering, DevOps, and Cloud and IaC, now is the time to &lt;a href="https://conference.pulumi.com/schedule/?utm_source=PulumiUP&amp;amp;utm_medium=web&amp;amp;utm_campaign=FY2025Q1_Event_PulumiUP"&gt;build your PulumiUP schedule&lt;/a&gt;. Select the sessions that match your goals and interests to maximize your experience. Plus, you&amp;rsquo;ll receive a link to watch your chosen panel discussions and tech talks on-demand!&lt;/p&gt;
&lt;p&gt;Haven’t registered yet? It’s not too late! Join 5,500 engineers worldwide in this groundbreaking event and gain the insights you need to drive innovation at your company. &lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Register now-&amp;gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can’t wait to see you there!&lt;/p&gt;</description><author>Sara Huddleston</author><category>pulumi-events</category><category>announcements</category><category>platform-engineering</category><category>ai</category><category>cloud-computing</category><category>infrastructure-as-code</category><category>devsecops</category><category>community</category></item><item><title>Platform Engineering: Cloud-Native, Maturity Models, and Platforms as Products</title><link>https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/</link><pubDate>Fri, 26 Jul 2024 17:40:17 +0000</pubDate><guid>https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/platform-engineering-cncf-maturity-model/index.png" /&gt;
&lt;p&gt;The Platform Engineering &amp;amp; DevOps in-person series launched in Berlin with two great speakers. This blog article is an overview of Dominik Kress&amp;rsquo;s talk, “What the Heck is the CNCF Platform Working Group? Answers from a Member!” in which he discussed Cloud-Native Platforms, The Platform Maturity Model, and approaching Platforms as Products.&lt;/p&gt;
&lt;p&gt;In this article, you&amp;rsquo;ll learn more about &lt;a href="https://www.pulumi.com/what-is/what-is-platform-engineering/"&gt;platform engineering&lt;/a&gt; and how to get involved with the CNCF Platform Working Group. Make sure to check our &lt;a href="https://www.meetup.com/pro/pugs/"&gt;Pulumi User Groups (PUGs)&lt;/a&gt; to find a meetup near you.&lt;/p&gt;
&lt;h2 id="on-this-platform-engineering-article"&gt;On this platform engineering article:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/#what-is-a-platform"&gt;What is a Platform?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/#defining-cloud-native-platforms"&gt;Defining Cloud Native Platforms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/#the-platform-maturity-model-charting-the-path-to-success"&gt;The Platform Maturity Model: Charting the Path to Success&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/#platforms-as-products-driving-success"&gt;Platforms as Products: Driving Success&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/#frequently-asked-questions"&gt;Frequently Asked Questions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-is-a-platform"&gt;What is a Platform?&lt;/h2&gt;
&lt;p&gt;According to CNCF, a platform in cloud-native computing is an integrated collection of capabilities designed to meet users&amp;rsquo; needs. It serves as a cross-cutting layer, ensuring a consistent experience integrating and managing services and capabilities for various applications and use cases. A good platform provides consistent user experiences through portals, project templates, and self-service APIs.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/case-studies/atlassian/"&gt;Atlassian&lt;/a&gt; describes platform teams as creators of capabilities used by multiple product teams, reducing their overhead and cognitive load. Martin Fowler and Evan Bottcher define a digital platform as a foundation of self-service APIs, tools, services, and support arranged as an internal product. These platforms enable autonomous teams to deliver features faster with less coordination.&lt;/p&gt;
&lt;p&gt;The specific capabilities of a platform are tailored to the needs of its stakeholders and users. While platform teams provide these capabilities, they do not always implement them directly. Managed service providers or dedicated internal teams can maintain the underlying implementations, ensuring consistency across the organization. Platforms are tailored to an enterprise’s internal users and are particularly relevant for cloud-native architectures, separating supporting capabilities from application-specific logic.&lt;/p&gt;
&lt;h2 id="defining-cloud-native-platforms"&gt;Defining Cloud Native Platforms&lt;/h2&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/NUPK5CCm6XA?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;The core of the discussion at the CNCF Platform Working Group is: &amp;ldquo;What exactly is a cloud-native platform, and why do organizations need one?&amp;rdquo;
A cloud-native platform is a strategic business initiative that enables organizations to deliver value more efficiently and effectively. It is characterized by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Vendor-neutrality&lt;/strong&gt;: A cloud-native platform should be open and agnostic, allowing organizations to leverage various technologies and services without being locked into a single vendor.
&lt;strong&gt;Scalability and flexibility&lt;/strong&gt;: The platform should be designed to accommodate the organization&amp;rsquo;s growing and changing needs, with the ability to add or remove components as needed easily.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/blog/software-developer-experience-devex-devx-devops-culture/"&gt;Developer-centricity&lt;/a&gt;&lt;/strong&gt;: The platform should empower developers to be more productive by providing self-service capabilities, streamlined workflows, and a consistent developer experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/blog/developer-portal-platform-teams/"&gt;Operational efficiency&lt;/a&gt;&lt;/strong&gt;: The platform should simplify and automate the management and maintenance of the underlying infrastructure, allowing the organization to focus on delivering value to customers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continuous improvement&lt;/strong&gt;: The platform should be designed with a mindset of continuous evolution, with regular updates and enhancements to address emerging needs and technologies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By aligning with these principles, organizations can achieve faster time-to-market, improved developer productivity, and reduced operational overhead.&lt;/p&gt;
&lt;h2 id="the-platform-maturity-model-charting-the-path-to-success"&gt;The Platform Maturity Model: Charting the Path to Success&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/platform-engineering-cncf-maturity-model/dominik-platform-engineering-berlin.png"
alt="Dominik Kress at the Berlin Pulumi Group meetup explaining the platform maturity model" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Dominik Kress at the Berlin Pulumi Group meetup explaining the platform maturity model&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The Platform Working Group has developed a Platform Maturity Model. This framework can help assess the current state of a cloud native platform and identify steps to enhance its maturity. It defines five levels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ad-hoc&lt;/strong&gt;: At the lowest level, the platform is ad-hoc, with no dedicated team or budget and a reliance on individual efforts and workarounds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operational&lt;/strong&gt;: The platform has a dedicated team and budget, which focus primarily on operational tasks and maintenance rather than strategic initiatives.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalable&lt;/strong&gt;: The platform is now viewed as a product with a clear roadmap and a focus on delivering value to internal customers. The platform team has more autonomy and the ability to drive innovation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enabled&lt;/strong&gt;: The platform has become a strategic asset, with a thriving ecosystem of contributors and consumers. The platform team is empowered to make decisions and drive the platform&amp;rsquo;s evolution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimized&lt;/strong&gt;: The platform is continuously optimized, focusing on measuring and improving key performance indicators. The platform is deeply integrated into the organization&amp;rsquo;s technology strategy and decision-making processes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By using the CNCF&amp;rsquo;s &lt;a href="https://tag-app-delivery.cncf.io/whitepapers/platform-eng-maturity-model/"&gt;Platform Maturity Model&lt;/a&gt; as a guide, organizations can assess their current level of platform maturity, identify areas for improvement, and develop a roadmap to reach a higher level of platform success. This model has proven to be a valuable tool for many organizations, helping them to align their platform initiatives with their broader business objectives.&lt;/p&gt;
&lt;h2 id="platforms-as-products-driving-success"&gt;Platforms as Products: Driving Success&lt;/h2&gt;
&lt;p&gt;One of the key initiatives currently underway within the Platform Working Group is the &amp;ldquo;&lt;a href="https://tag-app-delivery.cncf.io/blog/product-thinking-for-platforms/"&gt;Platforms as Products&lt;/a&gt;&amp;rdquo; research project. This effort aims to explore the parallels between traditional product management and the management of cloud-native platforms to identify best practices and patterns that can help organizations unlock their platforms&amp;rsquo; full potential.&lt;/p&gt;
&lt;p&gt;The core premise of the &amp;ldquo;Platforms as Products&amp;rdquo; initiative is that successful cloud-native platforms should be treated and managed like products rather than just technology projects. This means applying principles of product management, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Defining a clear vision and roadmap&lt;/strong&gt;: Establishing a long-term vision for the platform and a roadmap to get there, focusing on delivering value to internal customers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Measuring and optimizing for key metrics&lt;/strong&gt;: Identifying and tracking the right performance indicators to ensure the platform delivers the desired outcomes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fostering a thriving ecosystem&lt;/strong&gt;: Encouraging and enabling a community of contributors and consumers to drive the platform&amp;rsquo;s evolution and adoption.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continuously iterating and improving&lt;/strong&gt;: Embracing a continuous improvement mindset, with regular updates and enhancements to the platform based on user feedback and emerging needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By adopting a product management approach to their cloud native platforms, organizations can better align their platform initiatives with their broader business goals and ensure that the platform delivers tangible value to the organization.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This article and Dominik Kress&amp;rsquo;s talk highlighted the importance of platform engineering in cloud-native computing. Key points included defining cloud-native platforms, assessing platform maturity, and managing platforms with product management principles.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in learning more about platform engineering and getting involved in CNCF&amp;rsquo;s initiatives, there are several ways to participate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Register for the &lt;a href="https://info.pulumi.com/platform-engineering-workshop-series"&gt;Platform Engineering workshop series course&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Join the bi-weekly &lt;a href="https://tag-app-delivery.cncf.io/wgs/platforms/#meetings"&gt;CNCF Platform Working Group meetings&lt;/a&gt; every other Tuesday at 5 PM Berlin time (11 AM ET).&lt;/li&gt;
&lt;li&gt;Learn how to &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/developer-portals/"&gt;build Developer Portals with Pulumi&lt;/a&gt;. You can get off the ground faster with organization templates, a new project wizard, or leveraging the backstage plugin.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="frequently-asked-questions"&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;h3 id="what-is-the-cncf-platform-working-group"&gt;What is the CNCF Platform Working Group?&lt;/h3&gt;
&lt;p&gt;Within the &lt;a href="https://www.cncf.io/"&gt;CNCF&lt;/a&gt;, the Platform Working Group is a collaborative effort focused on the critical topic of cloud native platforms. As a working group member, you can share insights and experiences from our discussions.&lt;/p&gt;
&lt;p&gt;The Platform Working Group is part of the CNCF&amp;rsquo;s App Delivery Technical Advisory Group, which includes sustainability, runtime, observability, and security initiatives. The working group is open to anyone interested in contributing to the conversation around cloud native platforms, and its members come from diverse backgrounds, including product managers, engineers, and industry experts.&lt;/p&gt;
&lt;h3 id="who-is-dominik-kress"&gt;Who is Dominik Kress?&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/dominik-kress-33a540174/"&gt;Dominik Kress&lt;/a&gt; is a product manager at Giant Swarm and a CNCF Platforms Working Group member.&lt;/p&gt;
&lt;p&gt;He is on a mission to simplify developers&amp;rsquo; lives by delivering intuitive developer platforms. He has been in the IT industry for over seven years, starting his journey as a Full Stack Software Engineer, falling in love with DevOps and Product Organisations to become a Product Manager for Cloud Technology later.&lt;/p&gt;
&lt;p&gt;Dominik is passionate about Cloud Transformation, Product Management, and helping people. He loves contributing to the community with talks, articles, or publications.&lt;/p&gt;
&lt;h3 id="how-can-i-participate-in-the-platform-as-a-product-research"&gt;How can I participate in the Platform As A Product research?&lt;/h3&gt;
&lt;p&gt;The &amp;ldquo;Platforms as Products&amp;rdquo; research project is currently underway, with the Platform Working Group conducting interviews and gathering insights from organizations that have successfully implemented cloud native platforms. The goal is to distill these learnings into a set of best practices and patterns that can be shared with the broader community.&lt;/p&gt;
&lt;p&gt;To participate in this research, &lt;a href="https://bit.ly/platform-research"&gt;sign up here&lt;/a&gt;.&lt;/p&gt;</description><author>Sara Huddleston</author><category>platform-engineering</category><category>community</category><category>pulumi-events</category></item><item><title>Platform Engineering &amp; DevOps Series Kickoff Announcement</title><link>https://www.pulumi.com/blog/platform-engineering-devops-event-meetup-community/</link><pubDate>Mon, 15 Jul 2024 14:38:46 +0000</pubDate><guid>https://www.pulumi.com/blog/platform-engineering-devops-event-meetup-community/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/platform-engineering-devops-event-meetup-community/index.png" /&gt;
&lt;p&gt;We are excited to announce the kickoff of the Platform Engineering &amp;amp; DevOps Series, which will run from July 16 to October 31. This series will feature in-person events across various cities, including Berlin, London, Paris, Sydney, Boston, San Francisco, Seattle, Austin, Denver, and NYC. For those unable to attend an in-person event, we encourage you to participate in a virtual DevOps &amp;amp; Platform Engineering workshop.&lt;/p&gt;
&lt;h2 id="upcoming-in-person-events"&gt;Upcoming In-Person Events&lt;/h2&gt;
&lt;p&gt;Pulumi is hosting in-person meetups and virtual workshops for engineers interested in Platform Engineering and DevOps, covering topics from best practices to setup and implementation to advanced topics. Join us for tech talks, hands-on workshops, and opportunities to network with fellow engineers.&lt;/p&gt;
&lt;h3 id="first-platform-engineering--devops-in-person-event-berlin---july-16"&gt;First Platform Engineering &amp;amp; DevOps in-person event: Berlin - July 16&lt;/h3&gt;
&lt;p&gt;Join &lt;a href="https://www.linkedin.com/in/dominik-kress-33a540174/"&gt;Dominik Kress&lt;/a&gt; (Product Manager at Giant Swarm and member of the CNCF Platforms Working Group) and &lt;a href="https://www.linkedin.com/in/guy-menahem/"&gt;Guy Menahem&lt;/a&gt; (Solutions Architect at Komodor and community leader at The Platformers) at LOBE Block for an engaging discussion on platform engineering.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dominik Kress will present &amp;ldquo;What the Heck is the CNCF Platform Working Group? Answers from a Member!&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Guy Menahem will present &amp;ldquo;For This Backstage, You Don’t Need a Special Pass: Platform Engineering in Practice.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more details and to RSVP, visit the &lt;a href="https://www.meetup.com/berlin-pulumi-user-group/events/301456990/"&gt;Berlin Meetup page&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="second-in-person-event-boston-july-24"&gt;Second In-Person Event: Boston, July 24&lt;/h3&gt;
&lt;p&gt;Join Pulumi&amp;rsquo;s founder &amp;amp; CEO, &lt;a href="https://www.linkedin.com/in/joejduffy/"&gt;Joe Duffy&lt;/a&gt;, and &lt;a href="https://www.linkedin.com/in/jbaldanza/"&gt;Jamie Baldanza&lt;/a&gt;, Director of DevOps at Relay Therapeutics, for the launch of our Boston meetup at The Foundry. This is a great opportunity for DevOps engineers, platform engineers, software engineers, and Cloud enthusiasts to connect and share insights.&lt;/p&gt;
&lt;p&gt;RSVP is required due to limited capacity. Secure your spot, and RSVP at the &lt;a href="https://www.meetup.com/boston-pulumi-user-group/events/301985583/"&gt;Boston Meetup page&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="more-coming-soon"&gt;More coming soon!&lt;/h3&gt;
&lt;p&gt;We expected Seattle, Paris, and London&amp;rsquo;s meetups to happen in early September.
Details for the other in-person events will be coming soon, so stay tuned for more updates at &lt;a href="https://info.pulumi.com/platform-engineering-devops-series"&gt;Platform Engineering &amp;amp; DevOps Series&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;No upcoming in-person events in your area? Attend one of our virtual workshops and keep up with the latest in DevOps &amp;amp; Platform Engineering!&lt;/p&gt;
&lt;h3 id="virtual-workshops"&gt;Virtual Workshops&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Getting Started with CI/CD for AWS using GitHub Actions&lt;/strong&gt;: July 17. Learn more and &lt;a href="https://www.pulumi.com/resources/getting-started-with-ci-cd-aws-pulumi-github-actions/"&gt;register here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;From Zero to Production in Kubernetes&lt;/strong&gt;: July 25. Learn more and &lt;a href="https://www.pulumi.com/resources/from-zero-to-production-in-kubernetes/"&gt;register here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced CI/CD for AWS using Pulumi and GitHub Actions&lt;/strong&gt;: August 14. Learn more and &lt;a href="https://www.pulumi.com/resources/advanced-cicd-aws-pulumi-github-actions/"&gt;register here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mastering Platform Engineering: From Setup to Scaling Success&lt;/strong&gt;: TBD.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Join us for tech talks, hands-on workshops, and opportunities to network with industry peers. We are excited to meet you in person or virtually.
See you there!&lt;/p&gt;</description><author>Sara Huddleston</author><category>developer-experience</category><category>devops</category><category>platform-engineering</category><category>community</category><category>pulumi-events</category></item><item><title>Announcing PulumiUP Conference 2024</title><link>https://www.pulumi.com/blog/announcing-pulumiup-conference-2024/</link><pubDate>Wed, 01 May 2024 17:27:25 +0000</pubDate><guid>https://www.pulumi.com/blog/announcing-pulumiup-conference-2024/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/announcing-pulumiup-conference-2024/index.png" /&gt;
&lt;p&gt;Today we announce our annual PulumiUP virtual conference taking place on September 18, 2024. PulumiUP is our global cloud and IaC conference for anyone interested in infrastructure as code, cloud, AI, platform engineering, DevOps, and cloud culture. Every year, we strive to build a program packed with technical talks, demos, and best practices to empower you with new learnings and inspiration that you can apply in your professional life. Attend to hear from industry leaders, experts, and community peers.&lt;/p&gt;
&lt;h2 id="what-is-pulumiup"&gt;What is PulumiUP?&lt;/h2&gt;
&lt;p&gt;PulumiUP isn&amp;rsquo;t just another conference, it&amp;rsquo;s a global gathering of minds passionate about cloud technologies, AI, DevOps, and everything in between. Whether you&amp;rsquo;re an industry veteran or just dipping your toes into the vast ocean of cloud computing, PulumiUP has something for everyone.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll hear keynotes from Pulumi Founder/CEO Joe Duffy and CTO Luke Hoban, stories from industry leaders on their experiences with cloud adoption and transformation (and how they used Pulumi to make it happen), and talks from other members of the Pulumi community (like you!) aimed at helping you navigate the ever-changing world of the cloud.&lt;/p&gt;
&lt;h2 id="call-for-speakers-your-story-matters"&gt;Call for Speakers: Your Story Matters&lt;/h2&gt;
&lt;p&gt;One exciting addition to this year&amp;rsquo;s event is the call for speakers. We invite you, the community, to share your stories, experiences, and expertise with fellow attendees. Whether it&amp;rsquo;s a deep dive into a groundbreaking project, lessons learned from failures, or innovative best practices, your voice matters at PulumiUP.&lt;/p&gt;
&lt;h3 id="key-dates-to-remember"&gt;Key Dates to Remember&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CFP opens: Thursday, April 25, 2024.&lt;/li&gt;
&lt;li&gt;CFP closes: Monday, June 17, 2024.&lt;/li&gt;
&lt;li&gt;CFP Notifications: Monday, July 22, 2024.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="selection-criteria"&gt;Selection Criteria&lt;/h3&gt;
&lt;p&gt;At PulumiUP, diversity and originality are celebrated. We welcome proposals from all corners of the tech community and prioritize fresh perspectives and solutions. Regardless of where you are in the world, we want to hear from you. Whether you&amp;rsquo;re a seasoned speaker or a first-timer, we encourage you to submit your ideas. Just remember, no vendor pitches allowed!&lt;/p&gt;
&lt;h3 id="talk-formats-and-themes"&gt;Talk Formats and Themes&lt;/h3&gt;
&lt;p&gt;You can submit up to two proposals in either the Lightning Talk (15-minute) or traditional session (30-minute) formats. The conference will cover a wide array of themes, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Infrastructure as Code&lt;/strong&gt;: From cloud providers to Kubernetes, explore the latest trends and best practices in cloud computing and IaC.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Platform Engineering &amp;amp; DevOps&lt;/strong&gt;: Learn how to streamline CI/CD practices, automate infrastructure operations, build internal developer portals (IDP), and improve developer experiences.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI / ML&lt;/strong&gt;: Dive into the world of AI and ML with topics like deploying AI application, LLM models, MLOps, and AIOps.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloud Culture&lt;/strong&gt;: Discover the human side of tech, focusing on diversity, inclusivity, and collaboration within the industry.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Do you have a story to tell? &lt;a href="https://sessionize.com/pulumiup-conference-2024"&gt;Submit your proposal&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="join-us-on-september-18"&gt;Join Us on September 18!&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Register for PulumiUP&lt;/a&gt;. Stay tuned for more updates and announcements as we gear up for PulumiUP 2024. We can&amp;rsquo;t wait to see you there!&lt;/p&gt;</description><author>Sara Huddleston</author><category>pulumi-events</category></item><item><title>How AI is Transforming DevOps: AI Talks for DevOps Insights</title><link>https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/</link><pubDate>Mon, 13 Nov 2023 22:05:34 +0000</pubDate><guid>https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/index.png" /&gt;
&lt;p&gt;The integration of artificial intelligence (AI) with DevOps signals a new era in software development. DevOps possesses unique characteristics and needs that make it exceptionally compatible with AI augmentation. Given that code fundamentally relies on language, and large language models (LLMs) serve as the core of GPT functionality, these models are particularly well-suited for tasks such as code generation. This article unwraps the topics addressed during our “AI: Friends or Foe | AI Talks for DevOps” event in San Francisco.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#how-will-ai-impact-the-future-of-devops"&gt;How will AI Impact the Future of DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#what-is-devops-in-ai"&gt;What is DevOps in AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#what-is-ai-in-devops"&gt;What is AI in DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#how-ai-is-currently-used-in-devops"&gt;How AI is Currently Used in DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#how-can-a-devops-team-take-advantage-of-artificial-intelligence"&gt;How Can a DevOps Team Take Advantage of Artificial Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#top-5-skills-for-devops-engineers-in-the-ai-era"&gt;Top 5 Skills for DevOps Engineers in the AI era&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#how-to-overcome-ai-for-devops-challenges"&gt;How to Overcome AI for DevOps Challenges&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/#frequently-asked-questions"&gt;Frequently Asked Questions&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="how-will-ai-impact-the-future-of-devops"&gt;How will AI Impact the Future of DevOps&lt;/h2&gt;
&lt;p&gt;In the Fireside chat, Luke Hoban expressed his enthusiasm for incorporating AI into DevOps, emphasizing its potential utilization by both DevOps professionals and the development team. In contrast, Nana Janashia, &lt;a href="https://www.youtube.com/@TechWorldwithNana"&gt;TechWorld with Nana&lt;/a&gt;, adopted a more cautious stance, drawing attention to potential risks, particularly regarding reliability.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/i09F14yc0l4?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id="what-is-devops-in-ai"&gt;What is DevOps in AI&lt;/h2&gt;
&lt;p&gt;When considering the adoption of AI and AI engineering, such as prompt engineering and other specific disciplines, AI engineers rely heavily on the cloud. Many AI-based systems are built around cloud-native tools, practices, and managed services.&lt;/p&gt;
&lt;p&gt;The extensive use of cloud-native primitives means that AI is fundamentally a cloud adoption story. Consequently, established DevOps and &lt;a href="https://www.pulumi.com/what-is/what-is-infrastructure-as-code/"&gt;infrastructure as code&lt;/a&gt; tooling and best practices play an important role in AI engineering, in what is being done, and in leveraging its use.&lt;/p&gt;
&lt;h2 id="what-is-ai-in-devops"&gt;What is AI in DevOps&lt;/h2&gt;
&lt;p&gt;Integrating AI in DevOps entails employing machine learning (ML) and other artificial intelligence technologies to automate and optimize various software development and delivery aspects, including tasks such as automating testing and deployment processes and refining resource management.&lt;/p&gt;
&lt;p&gt;The incorporation of AI in DevOps can result in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enhanced speed&lt;/li&gt;
&lt;li&gt;Improved resource management&lt;/li&gt;
&lt;li&gt;Increased reliability throughout the software development lifecycle&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consequently, organizations may experience swifter deployments, reduced errors, and heightened overall productivity. By substituting manual processes with automation and AI-powered solutions, DevOps teams can elevate product quality and more efficiently oversee their systems.&lt;/p&gt;
&lt;h2 id="how-ai-is-currently-used-in-devops"&gt;How AI is Currently Used in DevOps&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/luke-nana-adora-discussing-devop-ai.png"
alt="Luke Hoban at the San Francisco Pulumi Group meetup discussing the usage of AI, during the AI Talks for DevOps" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Luke Hoban at the San Francisco Pulumi Group meetup discussing the usage of AI, during the AI Talks for DevOps&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;DevOps significantly impacts all stages of the development and operations lifecycle. It has helped break silos and optimize to increase developer velocity and productivity, creating a positive impact on the ops side.&lt;/p&gt;
&lt;p&gt;AI assists DevOps teams to refine their operations by detecting inefficiencies and triggering warnings as soon as issues appear. This technology also enables real-time observation of systems and applications, permitting prompt actions from operations personnel and minimizing downtime.&lt;/p&gt;
&lt;p&gt;AI-driven automation can also help the software development process with code generation. The operations teams from both departments quickly pinpoint any issues in their workflows while speeding up decision-making processes.&lt;/p&gt;
&lt;p&gt;In the long term, the AI may use cloud credentials to create and autonomously automate deployment and management and perform DevOps tasks on behalf of the DevOps or &lt;a href="https://www.pulumi.com/what-is/what-is-platform-engineering/"&gt;platform engineering&lt;/a&gt; team. In the near term, it is used to assist humans, from DevOps professionals to developers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;“In the near term, AI usage in DevOps is about how do you keep the human in the loop, how do you use it as a learning tool, as a code generation tool, and for auditing to provide actionable notifications, all of which are still very human-dependent. There is so much more it can be used for. Currently, it&amp;rsquo;s a tool serving humans. But it is fascinating to imagine it in the future when it can be trusted to be an autonomous agent.”&lt;/strong&gt;&lt;/em&gt; - &lt;em&gt;Luke Hoban, CTO of Pulumi and co-creator of TypeScript&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, how does this technology bring about these advancements? Two main ways are by streamlining development tasks and improving monitoring and security protocols.&lt;/p&gt;
&lt;h3 id="streamlining-development-workflows"&gt;Streamlining Development Workflows&lt;/h3&gt;
&lt;p&gt;AI has the potential to significantly change the software development life cycle by automating routine processes, using resources efficiently, and offering solutions for improved code. DevOps teams can leverage AI-driven tools to increase effectiveness when managing their assets while also improving code quality, leading to faster project deliveries.&lt;/p&gt;
&lt;p&gt;For instance, AI can identify any slowdowns during progress and recommend improvements, analyze root causes, and help make judicious decisions regarding resource allocation, ultimately resulting in efficient delivery of software products.&lt;/p&gt;
&lt;h3 id="enhancing-monitoring-and-security"&gt;Enhancing Monitoring and Security&lt;/h3&gt;
&lt;p&gt;The usage of AI significantly boosts DevOps monitoring and security. With the assistance of AI tools, operations teams can use machine learning algorithms to examine a massive amount of data to protect their applications from potential risks and enhance reliability. These algorithmic solutions provide valuable advice for development personnel, which helps strengthen protection measures while optimizing performance simultaneously.&lt;/p&gt;
&lt;h2 id="how-can-a-devops-team-take-advantage-of-artificial-intelligence"&gt;How Can a DevOps Team Take Advantage of Artificial Intelligence&lt;/h2&gt;
&lt;p&gt;A DevOps team can leverage AI in several ways to enhance efficiency, automation, and overall productivity. Here are some key strategies for a DevOps team to leverage AI:&lt;/p&gt;
&lt;h3 id="code-generation-and-learning"&gt;Code Generation and Learning&lt;/h3&gt;
&lt;p&gt;AI can be a powerful tool to make the development process much smoother. It can help engineers focus on what matters instead of searching for documentation on websites, developer forums, or search engines for answers to help solve specific problems. The perfect code snippet is often hard to find or may not even exist.&lt;/p&gt;
&lt;p&gt;Generative AI, powered by LLMs, can help developers and DevOps engineers quickly discover, learn, and, for example, use new cloud infrastructure APIs.&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/pulumi-ai/run-metabase-in-azure.png"
alt="Pulumi AI response to Run metabase in Azure, using TypeScript" width="90%"&gt;&lt;figcaption&gt;
&lt;p&gt;Pulumi AI response to Run metabase in Azure, using TypeScript&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can see it in practice &lt;a href="https://www.pulumi.com/blog/pulumi-ai/"&gt;using Pulumi AI&lt;/a&gt;. You can use natural language to ask for a specific cloud infrastructure goal and obtain a corresponding Pulumi program in your preferred programming language. Moreover, Pulumi AI facilitates the iterative refinement of your cloud infrastructure, incorporating new features, enhancements to security and performance, resolution of correctness issues, and clarification of requirements. &lt;a href="https://www.pulumi.com/product/neo/"&gt;Try Pulumi Neo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="intelligent-resource-management"&gt;Intelligent Resource Management&lt;/h3&gt;
&lt;p&gt;Platform and developer teams are spinning up resources across many cloud accounts within multiple cloud providers. It can be almost impossible to aggregate and search your infrastructure across these accounts since every cloud and every account is (by design!) a walled garden.&lt;/p&gt;
&lt;p&gt;Often, to answer key questions about their business, such as “Which team has the largest cloud footprint?”, teams need to combine data across various clouds, cloud accounts, and SaaS tools. This prevents organizations from getting quick answers to operational questions and barriers to building aggregations to derive insights. AI can provide actionable insights over infrastructure with natural language processing (NLP) queries.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;“I can get developers using IaC immediately with Pulumi Deployments and its GitHub integration, while Pulumi Insights [Resource Search] makes it really easy to find idle developer environments that need to be shut down, which reduces our cloud costs”&lt;/strong&gt;&lt;/em&gt; - &lt;em&gt;Santosh Dornal, Head of Software Test &amp;amp; DevOps, Alkira.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When using Pulumi Cloud, you can leverage &lt;a href="https://www.pulumi.com/blog/ai-assist-improvements/"&gt;AI Assist&lt;/a&gt;. You can provide a plain English (Spanish, French, or Japanese) request to express queries where you might not know the exact syntax, type tokens, or package names. AI Assist makes it easier by providing answers to queries like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;show me all s3 buckets not tagged in production&lt;/li&gt;
&lt;li&gt;show azure and azure native security groups&lt;/li&gt;
&lt;li&gt;show all AWS VPCs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="remediation-tool-continuous-and-automatic-compliance"&gt;Remediation Tool: Continuous and Automatic Compliance&lt;/h3&gt;
&lt;p&gt;Defining and managing security rules, criteria, and conditions are key to enabling security at scale. Policy as Code, or Compliance as Code, has the ability to verify and spot problems before deploying the infrastructure. When policies are written with code, you can apply software development practices such as testing, automated deployment, and version control.&lt;/p&gt;
&lt;p&gt;AI can be valuable not just in anomaly detection but also in remediation, which doesn&amp;rsquo;t just warn or error but can change the infrastructure directly to remediate compliance gaps. With Pulumi, &lt;a href="https://www.pulumi.com/blog/remediation-policies/"&gt;Remediation policies&lt;/a&gt; can be configured and applied across any subset of stacks within an organization.&lt;/p&gt;
&lt;p&gt;Consider the &lt;a href="https://techcrunch.com/2017/02/01/gitlab-suffers-major-backup-failure-after-data-deletion-incident/"&gt;unfortunate incident at GitLab&lt;/a&gt;, marked by a disastrous sequence of events resulting in the loss of segments of production databases and substantial user data.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/tLdRBsuvVKc?si=brUXETRY4Rew7954?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;In this scenario, AI could have swiftly pinpointed the root cause and proposed a rapid solution, potentially mitigating the extent of damage before it escalated.&lt;/p&gt;
&lt;p&gt;While the benefits of writing policies as code are evident for DevOps engineers, &lt;a href="https://www.pulumi.com/blog/benefits-of-policy-as-code/"&gt;the organizational benefits are even more significant&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="enhance-collaboration-and-communication"&gt;Enhance Collaboration and Communication&lt;/h3&gt;
&lt;p&gt;Nowadays, many professionals with DevOps in their titles are held accountable for the multiple aspects of Dev + Ops. At its core, DevOps is a cultural movement that removes barriers among teams and promotes collaboration and shared responsibility between dev and ops.&lt;/p&gt;
&lt;p&gt;DevOps teams have seen great benefits from AI-driven tools, particularly in improving transparency, encouraging feedback, providing quick answers to common queries, and automating routine tasks. Many major companies, like Microsoft, use AI to build efficient workflows that make better decisions, leading to increased business outcomes. This includes smoother application delivery, a prime function of DevOps initiatives.&lt;/p&gt;
&lt;h3 id="improved-product-delivery"&gt;Improved Product Delivery&lt;/h3&gt;
&lt;p&gt;Companies incorporating AI into their DevOps strategy reap the rewards of accelerated product delivery. This has been made possible through improved workflows, automated testing, and strengthened security measures, leading to greater efficiency in software development by allowing development and operations teams more scope for dealing with complex tasks using machine learning models. They can make better decisions, resulting in faster product delivery and enhanced business outcomes.&lt;/p&gt;
&lt;p&gt;By streamlining existing systems within this context, customers can benefit from superior products delivered faster than before while companies provide and reinforce their business value.&lt;/p&gt;
&lt;h3 id="planning-and-cost-optimization"&gt;Planning and Cost Optimization&lt;/h3&gt;
&lt;p&gt;Implementing AI algorithms or AI tools that analyze usage patterns can assist in predicting future resource needs and optimize cloud infrastructure costs. This also ties in with intelligent resource management mentioned before, which can enhance cost efficiency, optimize resource allocation, and prevent unnecessary expenses.&lt;/p&gt;
&lt;h2 id="top-5-skills-for-devops-engineers-in-the-ai-era"&gt;Top 5 Skills for DevOps Engineers in the AI Era&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/devops-ai-developer-future--pulumi-user-group-tech-talks/adora-nana-talking-angle.png"
alt="Adora Nwodo with Nana discussing skills that DevOps engineers will need to learn to make AI work" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Adora Nwodo with Nana discussing skills that DevOps engineers will need to learn to make AI work&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;DevOps engineers must open new skills, mainly in cloud services, data, and AI/ML.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Programming Languages&lt;/strong&gt;: Although DevOps don&amp;rsquo;t usually need to know general programming languages in-depth, they should know what is most used by application teams. It&amp;rsquo;s a nice-to-have to find errors in CI/CD pipelines and fix them themselves as needed, but it is a must-have if the goal is to work MLOps.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Infrastructure as Code&lt;/strong&gt;: Automation is important for DevOps and critical for MLOps. IaC, using familiar languages, has been used since the early days of MLOps and is a key component to solving the cloud orchestration challenge present in AI/ML. Dive into more detail in &lt;a href="https://www.pulumi.com/blog/mlops-the-ai-challenge-is-cloud-not-code/"&gt;The Real AI Challenge is Cloud, not Code!&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Continuous Integration and Delivery&lt;/strong&gt;: CI/CD is mandatory knowledge, and it must be understood in detail to predict data preparation code, AI/ML code, CI/CD code, and infrastructure-related code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom containers&lt;/strong&gt;: As a DevOps professional, you are expected to understand Docker and/or Kubernetes concepts and best practices.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Orchestration&lt;/strong&gt;: This is the holy grail of Ops and your key to unlocking AI.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/UfQeX-8HRmI?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id="how-to-overcome-ai-for-devops-challenges"&gt;How to Overcome AI for DevOps Challenges&lt;/h2&gt;
&lt;p&gt;The integration of AI in DevOps brings forth several challenges that organizations must navigate to leverage the full potential of these technologies. Here are some key challenges and potential strategies to overcome them:&lt;/p&gt;
&lt;h3 id="1-skills-and-expertise"&gt;1. Skills and Expertise&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: AI &amp;amp; ML expertise is often scarce within DevOps teams, leading to a skill gap in implementing and managing AI-driven tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overcoming Strategy&lt;/strong&gt;: Organizations will need to hire professionals with AI and ML expertise, or existing team members will need training in machine learning, becoming proficient in MLOps combined to DevOps principles. Collaboration between DevOps and data science teams can also bridge the knowledge gap.&lt;/p&gt;
&lt;h3 id="2-integration-complexity"&gt;2. Integration Complexity&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: Integrating AI seamlessly into existing DevOps workflows can be complex, given the diverse technologies and processes involved.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overcoming Strategy&lt;/strong&gt;: Prioritize a phased integration approach, gradually introducing AI capabilities into specific stages of the DevOps pipeline. This allows teams to adapt without disrupting established processes.&lt;/p&gt;
&lt;h3 id="3-scalability"&gt;3. Scalability&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: As AI applications within DevOps expand, ensuring scalability becomes crucial to accommodate growing workloads.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overcoming Strategy&lt;/strong&gt;: Design AI solutions with scalability in mind, utilizing cloud resources and containerization. Regularly assess performance and adjust infrastructure to meet evolving demands.&lt;/p&gt;
&lt;h3 id="4-data-quality-and-availability"&gt;4. Data Quality and Availability&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: AI models rely heavily on high-quality and readily available data. Inconsistent or inadequate data can lead to inaccurate predictions or suboptimal performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overcoming Strategy&lt;/strong&gt;: Prioritize data quality and establish robust data pipelines. Conduct regular audits to ensure data accuracy and implement strategies for handling missing or incomplete data.&lt;/p&gt;
&lt;h3 id="5-cultural-resistance"&gt;5. Cultural Resistance&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: Resistance to change or skepticism about the benefits of AI within DevOps and in software development can impede successful integration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overcoming Strategy&lt;/strong&gt;: Foster a culture of innovation and continuous improvement. Provide clear communication about the benefits of AI, involve team members in the decision-making process, and showcase success stories to build confidence.&lt;/p&gt;
&lt;p&gt;Navigating these challenges requires a thoughtful and strategic approach, focusing on collaboration, skill development, and the gradual incorporation of AI into existing DevOps practices. Regular evaluation and adaptation are essential to ensure a successful and sustainable integration of AI in the DevOps environment.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;AI in DevOps can transform software development by making workflows more efficient, monitoring and security stronger, and overall effectiveness increased. Organizations that embrace AI/ML aim for better collaboration between teams, automating and intelligently managing infrastructure, reducing time-to-market, and increasing developer productivity and cost savings due to streamlining processes within their development lifecycle. AI and ML knowledge will become necessary skills expected to be applied to enhance and benefit the development, security, and operation teams as a whole. Follow the Pulumi Python + AI/ML series to upskill and get ahead:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/mlops-the-ai-challenge-is-cloud-not-code/"&gt;The Real AI challenge is Cloud, not Code!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/mlops-huggingface-llm-aws-sagemaker-python/"&gt;Deploy AI Models on Amazon SageMaker using Pulumi Python IaC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/deploy-ai-ml-vercel-app/"&gt;Deploying Your AI/ML Chatbot Frontend To Vercel Using Pulumi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="frequently-asked-questions"&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;h3 id="can-ai-replace-devops"&gt;Can AI replace DevOps?&lt;/h3&gt;
&lt;p&gt;DevOps has not been taken over by AI yet. Rather, its use has made a difference in code quality and accelerated certain processes. Improvements to the quality of coding have been seen as one of the main benefits brought on through integration with artificial intelligence.&lt;/p&gt;
&lt;h3 id="what-is-an-example-of-ai-in-devops"&gt;What is an example of AI in DevOps?&lt;/h3&gt;
&lt;p&gt;AI can be utilized to make DevOps processes more efficient by creating test cases and pipelines, assessing infrastructure configurations for security concerns, and deploying applications. This technology includes machine learning algorithms, natural language processing systems, computer vision capabilities, chatbot programs, and virtual assistants. All are designed with one goal in mind – optimization of operations within development teams.&lt;/p&gt;
&lt;h3 id="what-is-the-future-of-devops"&gt;What is the future of DevOps?&lt;/h3&gt;
&lt;p&gt;Operations teams collaborating with developers to create quality products quickly and effectively is the goal for DevOps moving forward. The vision of this process involves both sides working together, resulting in an improved system and increased efficiency.&lt;/p&gt;</description><author>Sara Huddleston</author><author>Scott Lowe</author><category>devops</category><category>pulumi-events</category><category>ai</category><category>ml</category><category>community</category><category>platform-engineering</category></item><item><title>LangChain for DevOps: Learn LLM &amp; GenAI for Dev, Sec &amp; Ops</title><link>https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/</link><pubDate>Thu, 26 Oct 2023 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/generative-ai-apps-devops-talks-pulumi-user-group/index.png" /&gt;
&lt;p&gt;The emergence of DevOps revolutionized software development. Now, with AI powered tools like LangChain, these transformations are being accelerated. Unsurprisingly, our distinguished speaker at the launch of Pulumi&amp;rsquo;s in-person AI Talks, Patrick Debois, who coined the term &amp;ldquo;DevOps,&amp;rdquo; has recently tuned into LLM and GenAI Ops using the Langchain framework.&lt;/p&gt;
&lt;p&gt;This article unwraps the topics addressed during our &amp;ldquo;Generative AI, Apps, and DevOps | AI/ML Talks&amp;rdquo; event in Seattle, focusing on Langchain and GenAI for DevOps. You&amp;rsquo;ll be able to &lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#how-to-use-langchain-to-learn-llms-and-genai-for-devsecops"&gt;watch Patrick Debois teach LangChain to learn LLMs and GenAI&lt;/a&gt;, with code examples and lessons that are easily understood by traditional software engineering.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#what-is-langchain-used-for"&gt;What is LangChain used for?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#why-is-langchain-becoming-popular"&gt;Why is LangChain becoming popular?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#langchain-accelerating-devops"&gt;LangChain Accelerating DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#how-to-use-langchain-to-learn-llms-and-genai-for-devsecops"&gt;How to Use LangChain to Learn LLMs and GenAI for Dev(Sec)Ops&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#real-world-applications-of-langchain-ai-in-devops"&gt;Real-World Applications of LangChain AI in DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#monitoring-and-anomaly-detection-with-langchain-ai"&gt;Monitoring and Anomaly Detection with LangChain AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#future-ai-apps-and-devops"&gt;Future: AI, Apps, and DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/#frequently-asked-questions"&gt;Frequently Asked Questions&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="what-is-langchain-used-for"&gt;What is LangChain used for?&lt;/h2&gt;
&lt;p&gt;LangChain is an open-source Python framework designed to empower developers to construct robust generative AI applications. It facilitates the integration of advanced AI models such as OpenAI&amp;rsquo;s GPT, &lt;a href="https://gemini.google.com"&gt;Google&amp;rsquo;s Gemini&lt;/a&gt;, and &lt;a href="https://ai.meta.com/llama"&gt;Meta&amp;rsquo;s LLaMA&lt;/a&gt;. This versatile tool finds application in developing retrieval-augmented chatbots and other personalized assistants, utilizing technologies like ChatGPT. Furthermore, it enables tasks such as question-answering (GQA), summarization, code comprehension, API interactions, data cleansing, and much more.&lt;/p&gt;
&lt;h2 id="why-is-langchain-becoming-popular"&gt;Why is LangChain becoming popular?&lt;/h2&gt;
&lt;p&gt;The landscape of AI development is rapidly evolving, and LangChain is packed with incredible features for building LLM applications and tools. Developers with a wide range of expertise use LangChain for tasks such as managing interactions with language models, establishing seamless connections between diverse components, and integrating external resources like APIs and databases effortlessly.&lt;/p&gt;
&lt;p&gt;The LangChain platform hosts a diverse collection of APIs seamlessly integrated into applications. This enables developers to incorporate advanced language processing functionalities without the need for laborious construction from scratch.&lt;/p&gt;
&lt;h2 id="langchain-accelerating-devops"&gt;LangChain Accelerating DevOps&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/patrick-debois-langchain-ai-workshop.png"
alt="Patrick Debois at the Seattle Pulumi User Group, with a monitor showing OpenAI LangChain and code in Python" width="100%"&gt;&lt;figcaption&gt;
&lt;p&gt;Patrick Debois presenting the workshop Dev, Sec &amp;amp; Ops meet LangChain&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;LangChain can streamline the integration of large language models and data sources. By helping bring in AI capabilities, DevOps can revolutionize software development life cycles by making it easier for teams to handle challenges while optimizing resource allocation and usage through their cutting-edge, AI-powered solutions. This makes the &lt;a href="https://www.pulumi.com/docs/using-pulumi/automation-api/"&gt;automation of manual processes easier&lt;/a&gt; and the development of new resources far more accessible with faster utilization rates by leveraging artificial intelligence. Significantly important as &amp;ldquo;&lt;a href="https://www.pulumi.com/product/internal-developer-platforms/"&gt;Developer Velocity and Productivity&lt;/a&gt;&amp;rdquo; become business performance metrics across various industries.&lt;/p&gt;
&lt;p&gt;The features included in LangChain include chain interface memory functions for scalability within apps, control over dataflow, as storage – making code quality more reliable, plus seamless machine learning models integration, which allows them to build custom automated AI programs quickly. Thus providing users with an advanced but easy way of creating sophisticated solutions by combining their knowledge of coding and machine training models together.&lt;/p&gt;
&lt;h2 id="how-to-use-langchain-to-learn-llms-and-genai-for-devsecops"&gt;How to Use LangChain to Learn LLMs and GenAI for Dev(Sec)Ops&lt;/h2&gt;
&lt;p&gt;Patrick teaches in the way he would like to be taught. The workshop mainly uses the Langchain framework and basic Python knowledge. OpenAI will also need to be installed. You&amp;rsquo;ll learn essential skills in multiple use cases, applying Langchain for LLM application Development.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/iIl1bQnVwEs?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;You can see the breakdown of the lessons per role below, and find the code examples in the &lt;a href="https://github.com/jedi4ever/learning-llms-and-genai-for-dev-sec-ops/tree/main"&gt;Learning LLMs and GenAI for DevSecOps repo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="developer"&gt;Developer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Calling a simple LLM using OpenAI&lt;/li&gt;
&lt;li&gt;Looking at debugging in Langchain&lt;/li&gt;
&lt;li&gt;Chatting with OpenAI as a model&lt;/li&gt;
&lt;li&gt;Using prompt templates&lt;/li&gt;
&lt;li&gt;Use Docloader to read your local files and prepare them for the LLM&lt;/li&gt;
&lt;li&gt;Explain the calculation and use of embeddings&lt;/li&gt;
&lt;li&gt;Understand how splitting and chunking are important&lt;/li&gt;
&lt;li&gt;Loading embeddings and documents in a vector database&lt;/li&gt;
&lt;li&gt;Use a chain for Questions and Answers to implement the RAG pattern (Retrieval Augmented Generation)&lt;/li&gt;
&lt;li&gt;Show the use of OpenAI documentation to have the llm generate calls to find real-time information&lt;/li&gt;
&lt;li&gt;Implement an Agent and provide it with tools to get more real-time information&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="operations"&gt;Operations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Find out how many tokens you are using and the cost&lt;/li&gt;
&lt;li&gt;How to cache your calls to an LLM using exact matching or embeddings&lt;/li&gt;
&lt;li&gt;How to cache the calculation of embeddings and run the calculation locally&lt;/li&gt;
&lt;li&gt;Run your own local LLM (using Ollama)&lt;/li&gt;
&lt;li&gt;Track your calls and log them to a file (using a callback handler)&lt;/li&gt;
&lt;li&gt;Impose output structure (as JSON) and have the LLM retry if it&amp;rsquo;s not correct&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="security"&gt;Security&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Explain the OWASP top 10 for LLMS&lt;/li&gt;
&lt;li&gt;Show how simple prompt injection works and some mitigation strategies&lt;/li&gt;
&lt;li&gt;How to detect prompt injection using a 3rd party model from Hugging Face&lt;/li&gt;
&lt;li&gt;Detect project injection by using a prompt&lt;/li&gt;
&lt;li&gt;Check the answer LLMs provide and reflect if it is ok&lt;/li&gt;
&lt;li&gt;Use a Hugging Face model to detect if an LLM output was toxic&lt;/li&gt;
&lt;li&gt;Show a simple prompt for asking the LLM&amp;rsquo;s opinion on Kubernetes and Trivy vulnerabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="real-world-applications-of-langchain-ai-in-devops"&gt;Real-World Applications of LangChain AI in DevOps&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/langchain-vector-similarity-search-in-a-rag-application.png"
alt="Vector similarity search in a RAG application" width="90%"&gt;&lt;figcaption&gt;
&lt;p&gt;Vector similarity search in a RAG application. Credit to LangChain and Neo4J team&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;LangChain AI has practical applications in DevOps, particularly related to question-answering using documents as context, extraction, evaluation, and natural language processing tasks, all powered by AI tools. An interesting scenario is implementing &lt;a href="https://blog.langchain.dev/using-a-knowledge-graph-to-implement-a-devops-rag-application/"&gt;a knowledge graph based RAG application with LangChain&lt;/a&gt; to support the DevOps team.&lt;/p&gt;
&lt;p&gt;ChatGPT based on LLMs enabled with these AI tools is one of the foremost implementations at present. Tracking capabilities through LangChain enables developers to determine which prompts are more effective, thus supporting what artificial intelligence offers when integrated into development operations.&lt;/p&gt;
&lt;h2 id="monitoring-and-anomaly-detection-with-langchain-ai"&gt;Monitoring and Anomaly Detection with LangChain AI&lt;/h2&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/monitoring-llm-langchain-whylabs.png"
alt="Monitoring LLM performance with LangChain and LangKit" width="90%"&gt;&lt;figcaption&gt;
&lt;p&gt;Monitoring LLM performance with LangChain and LangKit. Credit to WhyLabs&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;LangChain AI provides an efficient approach to DevOps through continuous monitoring, and anomaly detection. LangChain&amp;rsquo;s integration in DevOps allows for intelligent monitoring of various system parameters, application performance metrics, and log files. It can process large volumes of data generated by applications and infrastructure components. Through natural language processing (NLP) techniques, LangChain can interpret logs, error messages, and system alerts in real-time.&lt;/p&gt;
&lt;p&gt;LangChain&amp;rsquo;s AI-driven anomaly detection capabilities are pivotal in identifying deviations from expected behavior in the monitored data. By analyzing historical data patterns, LangChain can learn the normal behavior of the system and its components. When the system encounters an unusual event or behavior, LangChain can promptly detect it as an anomaly. These anomalies could be security threats, performance bottlenecks, code quality, or any irregularities within the system.&lt;/p&gt;
&lt;p&gt;Keep in mind that monitoring LLM performance is important to ensure you can rely on the model&amp;rsquo;s accuracy and relevance in real-world applications. Our customer &lt;a href="https://www.pulumi.com/case-studies/whylabs/"&gt;WhyLabs&lt;/a&gt; has a great article showing the significance of &lt;a href="https://whylabs.ai/blog/posts/monitoring-llm-performance-with-langchain-and-langkit"&gt;monitoring LLMs performance with LangChain and how to get started&lt;/a&gt; with monitoring.&lt;/p&gt;
&lt;h2 id="future-ai-apps-and-devops"&gt;Future: AI, Apps, and DevOps&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/what-is/what-is-platform-engineering/"&gt;Platform engineering&lt;/a&gt;, DevOps, or MLOps may be the next steps in the AI-driven software development future. AI tools are the gateway to giving developers access to big language models that allow them to create highly sophisticated solutions.&lt;/p&gt;
&lt;h3 id="accelerating-development-with-ai-powered-tools"&gt;Accelerating Development with AI-Powered Tools&lt;/h3&gt;
&lt;p&gt;AI-powered tools are revolutionizing the development process, enabling DevOps teams to access intelligent recommendations and improve code quality or obtain suggestions on new ways to accomplish goals. An example is the usage of &lt;a href="https://www.pulumi.com/product/neo/"&gt;Pulumi Neo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tools like LangChain, Amazon CodeGuru, and Pulumi AI provide actionable insights for efficient resource utilization while enforcing policy and compliance best practices. An &lt;a href="https://www.pulumi.com/blog/pulumi-insights-ai-cli/"&gt;IaC that leverages AI empowers teams&lt;/a&gt; to automate and more effectively manage infrastructure.&lt;/p&gt;
&lt;p&gt;Developers can reap multiple benefits from higher quality assessment of code lines, instantaneous detection of policy and security issues, useful cues on how to resolve problems, and improving code quality, productivity, and time management.&lt;/p&gt;
&lt;p&gt;AI has greatly impacted optimization during the review stage, providing developers with better insights into performance issues, code effectiveness, and &lt;a href="https://www.pulumi.com/blog/property-search/"&gt;resource utilization&lt;/a&gt; without any extra effort.&lt;/p&gt;
&lt;h3 id="security-and-vulnerability-management-with-ai"&gt;Security and Vulnerability Management with AI&lt;/h3&gt;
&lt;p&gt;The marriage of AI, machine learning, and DevOps/DevSecOps practices revolutionizes security and vulnerability management in software engineering. AI-enabled tools technologies not only strengthen the defenses of software systems but also enable organizations to stay one step ahead in ensuring successful deployments by removing manual processes through automation, using single sources of truth, enforcing least-privileged access through role-based access controls, and &lt;a href="https://www.pulumi.com/blog/remediation-policies/"&gt;automated remediation to correct configuration violations&lt;/a&gt; like auto-tagging, removing Internet access, and enabling storage encryption.&lt;/p&gt;
&lt;p&gt;DevSecOps can foster collaboration between developers, security, and operations and still enhance security and compliance best practices using Artificial Intelligence (AI) and Machine Learning techniques.&lt;/p&gt;
&lt;h3 id="leveraging-machine-learning-in-devops"&gt;Leveraging Machine Learning in DevOps&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/generative-ai-apps-devops-talks-pulumi-user-group/ml-dev-ops-cycle.png" alt="MLOps (Machine Learning Operations) meets DevOps Infinity Loop as part of the software development lifecycle" title="MLOps (Machine Learning Operations) meets DevOps Infinity Loop"&gt;&lt;/p&gt;
&lt;p&gt;Applying Machine Learning in DevOps is a game-changer. Not only does it automate and enhance various processes but also brings an intelligent, predictive, and adaptive dimension to development workflows. By embracing these technologies, development teams can achieve higher efficiency, improve code quality, optimize performance, and seamlessly integrate with artificial intelligence, thereby shaping the future of software engineering.&lt;/p&gt;
&lt;p&gt;ML models can evaluate past outcomes from compilation/builds plus performance metrics within an operation so that developers may leverage these insights when writing code accordingly with machine learning algorithms, allowing them to identify vulnerabilities or issues faster through root cause analysis while ameliorating system security against outside attacks like hackers or DDOS activity thus boosting overall system productivity thanks to AI implementation into existing processes.&lt;/p&gt;
&lt;h3 id="implementing-ai-models-into-devops-key-considerations"&gt;Implementing AI models into DevOps: Key Considerations&lt;/h3&gt;
&lt;p&gt;When considering AI, it&amp;rsquo;s essential to assess data quality, integration complexity, cost savings, and ethical/legal considerations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ensuring the data used for training these AI tools are precise, exhaustive, and up-to-date will help gain more reliable results.&lt;/li&gt;
&lt;li&gt;An important aspect of the implementation process is integrating existing DevOps instruments and guaranteeing scalability, depending on the company&amp;rsquo;s necessities.&lt;/li&gt;
&lt;li&gt;Ensuring that all laws applicable when working with such technology.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;AI and ML are rapidly becoming a necessity, which can greatly enhance and benefit Development, Security, and Operation teams. At first glance, it may appear daunting or out of reach, but tools like Langchain and Pulumi can make it easier to get started. Follow the Pulumi Python + AI/ML series to upskill and get ahead:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/mlops-the-ai-challenge-is-cloud-not-code/"&gt;The Real AI challenge is Cloud, not Code!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/mlops-huggingface-llm-aws-sagemaker-python/"&gt;Deploy AI Models on Amazon SageMaker using Pulumi Python IaC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/deploy-ai-ml-vercel-app/"&gt;Deploying Your AI/ML Chatbot Frontend To Vercel Using Pulumi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="frequently-asked-questions"&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;h3 id="who-is-patrick-debois"&gt;Who is Patrick Debois?&lt;/h3&gt;
&lt;p&gt;Patrick Debois is a highly accomplished technologist whose expertise spans the domains of Development (Dev), Security (Sec), and Operations (Ops). Acknowledged as a respected confidant within the developer, security, and operations communities, Patrick is presently deeply engrossed in the realm of Artificial Intelligence and Machine Learning, continually pushing the boundaries of his technical acumen.&lt;/p&gt;
&lt;p&gt;He was the organizer of the inaugural DevOpsDays in 2009. He is credited with coining &amp;ldquo;DevOps&amp;rdquo; and co-authoring the renowned DevOps Handbook. In the past, Patrick has collaborated with esteemed technology organizations such as &lt;a href="https://www.pulumi.com/case-studies/atlassian/"&gt;Atlassian&lt;/a&gt; and Snyk. Currently, he wears dual hats as the Vice President of Engineering and a Distinguished Engineer at Showpad.&lt;/p&gt;
&lt;h3 id="is-langchain-free"&gt;Is LangChain Free?&lt;/h3&gt;
&lt;p&gt;Yes, LangChain is an open-source framework, free to use and modify.&lt;/p&gt;
&lt;h3 id="how-does-langchain-work"&gt;How Does LangChain Work?&lt;/h3&gt;
&lt;p&gt;LangChain is a meticulously designed open-source framework tailored to simplify the creation of applications powered by large language models (LLMs). First, you will need to have a language model or you can use a public language model or train your own.&lt;/p&gt;
&lt;p&gt;Once you have a language model ready, you can start building applications. The framework offers an array of tools and APIs, simplifying the process of connecting language models to diverse data sources, interacting with their environment, and constructing intricate applications.&lt;/p&gt;
&lt;p&gt;LangChain operates by linking together various components, referred to as links, to establish a workflow. Each link in the chain performs a task and is connected in a sequence, enabling the output of one link to serve as the input for the subsequent one. This sequential linking allows the chain to execute intricate tasks by combining simple tasks seamlessly.&lt;/p&gt;
&lt;p&gt;See &lt;a href="https://python.langchain.com/docs/get_started/introduction"&gt;LangChain&amp;rsquo;s get started&lt;/a&gt; docs for more information.&lt;/p&gt;
&lt;h3 id="does-chatgpt-use-langchain"&gt;Does ChatGPT use LangChain?&lt;/h3&gt;
&lt;p&gt;ChatGPT utilizes LangChain to create custom artificial intelligence (AI). This allows for an individualized experience.&lt;/p&gt;</description><author>Sara Huddleston</author><author>Kat Morgan</author><category>pulumi-events</category><category>community</category><category>ai</category><category>devops</category><category>langchain</category><category>ml</category></item><item><title>Pulumi 💜's Open Source</title><link>https://www.pulumi.com/blog/pulumi-hearts-opensource/</link><pubDate>Fri, 11 Aug 2023 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumi-hearts-opensource/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-hearts-opensource/index.png" /&gt;
&lt;p&gt;Pulumi stands with the open source community.&lt;/p&gt;
&lt;p&gt;We are unaffected by HashiCorp relicensing their software yesterday, and express profound support for many of our cloud friends who have been affected.&lt;/p&gt;
&lt;p&gt;Pulumi is &lt;a href="https://github.com/pulumi/pulumi"&gt;true open source&lt;/a&gt;, uses the Apache 2.0 license, and does not and never will depend on BSL-licensed software in any way, HashiCorp owned or otherwise.&lt;/p&gt;
&lt;p&gt;We look forward to continuing to serve our &lt;a href="https://app.pulumi.com/signup"&gt;new&lt;/a&gt; and loyal customers, always with open source and our amazing, fast-growing community at our core.&lt;/p&gt;</description><author>Joe Duffy</author><category>open-source</category><category>license</category><category>apache</category><category>bsl</category></item><item><title>Announcing the Speaker Lineup for PulumiUP 2023</title><link>https://www.pulumi.com/blog/announcing-speaker-lineup-pulumiup-2023/</link><pubDate>Wed, 24 May 2023 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/announcing-speaker-lineup-pulumiup-2023/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/announcing-speaker-lineup-pulumiup-2023/index.png" /&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/pulumi-up/"&gt;PulumiUP&lt;/a&gt; is our virtual user conference for the Pulumi community and anyone interested in Infrastructure as Code. Every year, we strive to build a program packed with technical talks, demos, and best practices with the goal of leaving you with new learnings and inspiration that will help you become a better cloud engineer. You&amp;rsquo;ll hear from industry leaders and experts about IaC, software engineering, DevOps, Platform engineering, and AI.&lt;/p&gt;
&lt;p&gt;We hope you&amp;rsquo;ll &lt;a href="https://www.pulumi.com/pulumi-up/"&gt;join us virtually&lt;/a&gt; and take this opportunity to grow your knowledge and become infrastructure as code stars.&lt;/p&gt;
&lt;h2 id="get-ready-for-amazing-launches-and-demos"&gt;Get Ready for Amazing Launches and Demos&lt;/h2&gt;
&lt;p&gt;Learn about Pulumi&amp;rsquo;s newest features across the core IaC SDKs and Pulumi Cloud.
And watch hands-on demos by the Pulumi team:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Joe Duffy, Co-founder and CEO&lt;/li&gt;
&lt;li&gt;Luke Hoban, Co-creator of TypeScript and CTO&lt;/li&gt;
&lt;li&gt;Meagan Cojocar, Principal Product Manager&lt;/li&gt;
&lt;li&gt;Evan Boyle, Engineering Manager&lt;/li&gt;
&lt;li&gt;Zaid Ajaj, Software Engineer&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="final-speakers-announced"&gt;Final Speakers Announced&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ll hear from innovators, leaders, and experts from multiple industries and learn about infrastructure as code, software engineering, and cloud engineering.&lt;/p&gt;
&lt;h3 id="sam-cogan---solution-architect-wtw"&gt;Sam Cogan - Solution Architect, WTW&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: Keeping your Infrastructure Code DRY (Don&amp;rsquo;t Repeat Yourself)&lt;/em&gt;&lt;br&gt;
Sam is a Solution Architect with &lt;a href="https://www.wtwco.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;WTW&lt;/a&gt; and a Microsoft Azure MVP. Sam is focused on delivering applications into the cloud using IaaS, PaaS, Serverless, Containers, and Kubernetes. Sam is particularly focused on automation and DevOps, including Infrastructure as Code, Cloud automation tooling, PowerShell, and CI/CD tooling.&lt;/p&gt;
&lt;h3 id="dennis-sauvé---devops-engineer-washington-trust-bank"&gt;Dennis Sauvé - DevOps Engineer, Washington Trust Bank&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: How a Bank Modernized its Software Engineering with Infrastructure as Code Automation&lt;/em&gt;&lt;br&gt;
Dennis is a development operations engineer at &lt;a href="https://www.watrust.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Washington Trust Bank&lt;/a&gt; in Spokane, WA. With years of experience in software development and cloud engineering, he works to streamline deployment pipelines and create solutions for developers.&lt;/p&gt;
&lt;h3 id="ala-shiban---co-founder--ceo-klotho"&gt;Ala Shiban - Co-Founder &amp;amp; CEO, Klotho&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: Creating a &amp;lsquo;Cloud-Aware&amp;rsquo; Code Solution&lt;/em&gt;&lt;br&gt;
Ala is the co-founder of &lt;a href="https://klo.dev/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Klotho&lt;/a&gt;, a startup that transforms plain code to cloud-native code. He started his journey on Commodore64 with cassette tapes and (much) more recently worked on distributed systems, developer tools, and large-scale web, cloud, and microservice backends.&lt;/p&gt;
&lt;p&gt;He&amp;rsquo;s led smaller teams and larger organizations at Microsoft&amp;rsquo;s Developer Division and Riot Games&amp;rsquo; Infrastructure Platform organization.&lt;/p&gt;
&lt;h3 id="matt-stephenson---sr-principal-software-engineer-starburst-data"&gt;Matt Stephenson - Sr. Principal Software Engineer, Starburst Data&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: Creating Infrastructure Automation Magic with Code&lt;/em&gt;&lt;br&gt;
Matt is a Sr. Principal Software Engineer at &lt;a href="https://www.starburst.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Starburst Data&lt;/a&gt;. He&amp;rsquo;s responsible for Starburst&amp;rsquo;s infrastructure architecture. He&amp;rsquo;s worked at many tech companies, including Square, Oracle, Google, and Amazon. Aside from technology, Matt is a pilot and helps build The Man for Burning Man each year.&lt;/p&gt;
&lt;h3 id="tim-holm---co-founder--cto-nitric"&gt;Tim Holm - Co-Founder &amp;amp; CTO, Nitric&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: Engineering a Multi-cloud Platform&lt;/em&gt;&lt;br&gt;
Tim Holm is the Co-founder and CTO at &lt;a href="https://nitric.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Nitric&lt;/a&gt;, with 12 years of experience in software engineering and cloud development. In disciplines ranging from Server and Storage Virtualisation and Automation, Mobile Application development, Full-stack application development, and Cloud infrastructure automation. Before founding Nitric, Tim worked to deliver critical infrastructure projects in Government and Fintech.&lt;/p&gt;
&lt;p&gt;In his spare time, Tim enjoys video games, building Lego, and mountain biking.&lt;/p&gt;
&lt;h3 id="tyler-scheuble---head-of-platform-people-data-labs"&gt;Tyler Scheuble - Head of Platform, People Data Labs&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: Using Monorepos to Level-up your Infrastructure as Code and Software Delivery&lt;/em&gt;&lt;br&gt;
Tyler possesses a genuine enthusiasm for technology. At &lt;a href="https://www.peopledatalabs.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;People Data Labs&lt;/a&gt;, he has designed petabyte-scale data pipelines and high-performance APIs with demanding availability requirements, which informed his approach to leading the development of the next generation of the startup&amp;rsquo;s development pipelines and environments.&lt;/p&gt;
&lt;p&gt;Tyler is passionate about finding simple solutions to cross-cutting concerns such as security, observability, and development velocity.&lt;/p&gt;
&lt;h3 id="sefi-genis---co-founder--cto-firefly"&gt;Sefi Genis - Co-Founder &amp;amp; CTO, Firefly&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Talk: Lessons Learned from Writing Thousands of Lines of IaC&lt;/em&gt;&lt;br&gt;
Sefi is the CTO and Co-Founder at &lt;a href="https://www.gofirefly.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Firefly&lt;/a&gt;. He started his career in the 8200 Unit of the Israeli Intelligence Corps and then continued on to security and developer tooling companies.&lt;/p&gt;
&lt;p&gt;Sefi was a founding engineer at Dome9 Security (later acquired by Checkpoint), where he led the Backend Infrastructure of the product post-acquisition. Before founding Firefly, he became Head of Engineering in an Israeli cybersecurity startup company. Today he is building Firefly to help engineers manage the new reality of cloud-native operations.&lt;/p&gt;
&lt;h2 id="panel-discussion---ai-and-the-future-of-cloud-development"&gt;Panel Discussion - AI and the Future of Cloud Development&lt;/h2&gt;
&lt;p&gt;Prepare yourself for the future of cloud development! Gain valuable insights from industry experts in our panel discussion, where we explore the transformative impact of AI on the cloud infrastructure and software engineering industries. The panel discussion will be moderated by CEO Joe Duffy. These are the panelists:&lt;/p&gt;
&lt;h3 id="amanda-silver---cvp-developer-tools-microsoft"&gt;Amanda Silver - CVP Developer Tools, Microsoft&lt;/h3&gt;
&lt;p&gt;Amanda is the CVP of PM for &lt;a href="https://developer.microsoft.com/en-us/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Microsoft&amp;rsquo;s Developer Division&lt;/a&gt;, including the Visual Studio family of products, .NET, TypeScript, and our developer platforms. She has been key to Microsoft&amp;rsquo;s transformation to contribute to open source with the introduction of TypeScript, Visual Studio Code, and the acquisition of both Xamarin and GitHub. She believes that a tight digital feedback loop with zero distance between end-users and engineering teams is a critical element of great product development.&lt;/p&gt;
&lt;h3 id="beyang-liu---co-founder---cto-sourcegraph"&gt;Beyang Liu - Co-Founder &amp;amp; CTO, Sourcegraph&lt;/h3&gt;
&lt;p&gt;Beyang is the CTO and co-founder of Sourcegraph. Prior to Sourcegraph, Beyang was a software engineer at Palantir Technologies, where he developed new data analysis software on a small, customer-facing team working with Fortune 500 companies. Beyang studied Computer Science at Stanford, where he published research in probabilistic graphical models and computer vision at the Stanford AI Lab and thoroughly enjoyed his compilers course.&lt;/p&gt;
&lt;h3 id="luke-hoban---typescript-co-creator-and-cto-pulumi"&gt;Luke Hoban - TypeScript Co-Creator and CTO, Pulumi&lt;/h3&gt;
&lt;p&gt;Luke is CTO at Pulumi. He has worked on developer tools his entire career. He started out on Visual Studio, C#, and .NET in the early 2000s, later joined the ECMAScript standards body as a representative of Microsoft and then became one of the co-founders of the TypeScript programming language.&lt;/p&gt;
&lt;h2 id="featured-partners"&gt;Featured Partners&lt;/h2&gt;
&lt;p&gt;Thank you to our amazing partners for supporting PulumiUP! Visit these booths for tech talks, demos and Q&amp;amp;A about your favorite cloud platforms and developer tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;AWS&lt;/a&gt; - Solutions Architects will be on hand to demo the latest AWS and Pulumi capabilities and help you get the most from the AWS platform.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Google Cloud&lt;/a&gt; - Customer Engineers will help you accelerate your cloud journey with helpful tips and Q&amp;amp;A.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://azure.microsoft.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Microsoft&lt;/a&gt; - Cloud Advocates will be available to show you how to kickstart your projects on Azure.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.equinix.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Equinix&lt;/a&gt; - Stop by the Equinix booth to learn all about the new Equinix Pulumi provider.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://circleci.com/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;CircleCI&lt;/a&gt; - Stop by the CircleCI booth to learn best practices for adopting CI/CD in your organization.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.newrelic.com/pulumi/get-started-pulumi/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;New Relic&lt;/a&gt; - The New Relic team will demonstrate how to get started with Observability as Code with Pulumi and New Relic.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gofirefly.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Firefly&lt;/a&gt; - If you have existing cloud resources you can convert them to Pulumi code easily with Firefly. Stop by the Firefly booth for a demo.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nitric.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Nitric&lt;/a&gt; - The Nitric team will be on site to show you how to create cloud-agnostic infrastructure code from your application code.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://klo.dev/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Klotho&lt;/a&gt; - The Klotho team will show you how devops teams an application teams can easily collaborate to moderize and scale infrastructure without disruptions.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.getport.io/?utm_source=Pulumi.com&amp;amp;utm_medium=Website&amp;amp;utm_campaign=PulumiUP"&gt;Port&lt;/a&gt; - Join the Port team to learn how to setup a self-service portal for your developers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Want to attend PulumiUP 2023? &lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Register now!&lt;/a&gt;&lt;/p&gt;</description><author>George Huang</author><author>Sara Huddleston</author><author>Isaac Harris</author><category>announcements</category><category>pulumi-events</category></item><item><title>Join a Pulumi User Group (PUG) Meetup!</title><link>https://www.pulumi.com/blog/join-pulumi-user-group-community/</link><pubDate>Mon, 01 May 2023 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/join-pulumi-user-group-community/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/join-pulumi-user-group-community/index.png" /&gt;
&lt;p&gt;We have a global community made up of people from many different countries, but we also have many local communities. We want to enable our users to meet, share knowledge and ideas, answer questions, and learn about Pulumi and best practices. For that reason, we created the &lt;a href="https://www.meetup.com/pro/pugs"&gt;Pulumi User Groups, aka PUGs&lt;/a&gt; on Meetup.&lt;/p&gt;
&lt;p&gt;Members of PUGs will have access to a global network of experts who can offer help, advice, and support on using Pulumi effectively. The PUGs will also feature regular in-person meetups, webinars, in-person and virtual workshops, and other events to help members stay up-to-date with the latest cloud infrastructure and Pulumi developments.&lt;/p&gt;
&lt;h2 id="23-pulumi-user-groups-pugs-meetups-in-10-countries"&gt;23 Pulumi User Groups (PUGs) Meetups in 10 countries&lt;/h2&gt;
&lt;p&gt;PUGs are led by Pulumi employees and &lt;a href="https://www.pulumi.com/community/puluminaries/"&gt;Puluminaries&lt;/a&gt;, who are passionate community members that are experts in topics related to cloud infrastructure, Pulumi Cloud, cloud-native software development, and much more, and are willing to share their knowledge with the community.&lt;/p&gt;
&lt;h3 id="united-states-pulumi-user-groups"&gt;United States Pulumi User Groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/pulumi-seattle/"&gt;Seattle Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/new-york-pulumi-user-group/"&gt;New York Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/san-francisco-pulumi-user-group/"&gt;San Francisco Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/san-diego-pulumi-user-group/"&gt;San Diego Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/austin-pulumi-user-group/"&gt;Austin Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/denver-pulumi-user-group/"&gt;Denver Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/chicago-pulumi-user-group/"&gt;Chicago Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/columbus-pulumi-user-group/"&gt;Columbus Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/philadelphia-pulumi-user-group/"&gt;Philadelphia Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/boston-pulumi-user-group"&gt;Boston Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/detroit-pulumi-user-group"&gt;Detroit Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/nashville-pulumi-user-group"&gt;Nashville Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="south-america-pulumi-user-groups"&gt;South America Pulumi User Groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/sao-paulo-pulumi-user-group"&gt;São Paulo Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="european-pulumi-user-groups"&gt;European Pulumi User Groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/london-pulumi-user-group/"&gt;London Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/oslo-pulumi-user-group/"&gt;Oslo Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/berlin-pulumi-user-group/"&gt;Berlin Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/munich-pulumi-user-group/"&gt;Munich Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/prague-pulumi-user-group/"&gt;Prague Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="middle-east-pulumi-user-groups"&gt;Middle East Pulumi User Groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/tel-aviv-pulumi-user-group/"&gt;Tel Aviv Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="asia-pulumi-user-groups"&gt;Asia Pulumi User Groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/singapore-pulumi-user-group/"&gt;Singapore Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="oceania-pulumi-user-groups"&gt;Oceania Pulumi User Groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/australia-pulumi-user-group/"&gt;Australia Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/auckland-pulumi-user-group/"&gt;Auckland Pulumi User Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-first-pug-in-person"&gt;The First PUG in person&lt;/h2&gt;
&lt;p&gt;Our very first in-person PUG meetup took place in London, UK. The event was well-attended by developers, cloud architects, and other infrastructure enthusiasts. The attendees had the opportunity to network with other like-minded professionals and learn more about Pulumi&amp;rsquo;s tools and features from expert speakers.&lt;/p&gt;
&lt;p&gt;During the meetup, attendees heard from several speakers, including Joe Duffy, Co-Founder &amp;amp; CEO at Pulumi, who was there to speak about Infrastructure as Code that writes itself after the release of &lt;a href="https://www.pulumi.com/blog/pulumi-insights/"&gt;Pulumi Insights&lt;/a&gt;, which happened that same day.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/join-pulumi-user-group-community/pulumi-user-group-pug-london-joe-duffy.png" alt="Photo of Pulumi CEO Joe Duffy speaking at a Pulumi User Group (PUG) in London, UK"&gt;&lt;/p&gt;
&lt;p&gt;Other speakers included Liam Hampton, Sr. Regional Cloud Advocate at Microsoft, who spoke about Microsoft Azure and IaC, and Sam Cogan, Director of Solution Architecture at Willis Towers Watson, who spoke about building a library of reusable modules you can repeatedly reuse in your IaC projects.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/join-pulumi-user-group-community/pulumi-user-group-pug-london-sam-cogan.png" alt="Photo of Sam Cogan speaking at a Pulumi User Group (PUG) in London, UK"&gt;&lt;/p&gt;
&lt;p&gt;Overall, the first PUG meetup was a huge success, and attendees left feeling inspired and energized about Pulumi&amp;rsquo;s tools and the community&amp;rsquo;s possibilities. With the launch of PUGs, Pulumi is demonstrating its commitment to building a strong and supportive community of professionals passionate about cloud infrastructure.&lt;/p&gt;
&lt;h2 id="more-pugs-and-events-to-come"&gt;More PUGs and events to come&lt;/h2&gt;
&lt;p&gt;We are planning more in-person PUG events for the months to come. With PUGs, you&amp;rsquo;ll have the opportunity to connect with like-minded professionals, share knowledge and best practices, and stay up-to-date with the latest developments in cloud infrastructure and Pulumi.&lt;/p&gt;
&lt;p&gt;Join the &lt;a href="https://www.meetup.com/pro/pugs"&gt;Pulumi User Groups&lt;/a&gt; in your local area, or if there isn’t one yet, you are welcome to join the &lt;a href="https://slack.pulumi.com/"&gt;Pulumi Slack community&lt;/a&gt; and meet people from all over the world.&lt;/p&gt;</description><author>Sara Huddleston</author><category>announcements</category><category>community</category><category>pulumi-events</category></item><item><title>International Women's Day: Celebrating our Women in Tech</title><link>https://www.pulumi.com/blog/international-women-day-celebrating-women-in-tech/</link><pubDate>Wed, 08 Mar 2023 13:00:00 -0800</pubDate><guid>https://www.pulumi.com/blog/international-women-day-celebrating-women-in-tech/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/international-women-day-celebrating-women-in-tech/index.png" /&gt;
&lt;p&gt;Today is International Women&amp;rsquo;s Day, and this year the theme is #EmbraceEquity - which means creating an equitable environment. An equitable work environment means understanding that everyone, regardless of gender, religion, ethnicity, background, or resources, brings strength to the workforce and that opportunities should be given to them based on their individual needs.&lt;/p&gt;
&lt;p&gt;For Pulumi, it means a work environment where everyone can share ideas and respect them even when disagreeing. Women&amp;rsquo;s experiences - as well as men&amp;rsquo;s and nonbinary&amp;rsquo;s experiences - inform the direction of digital technology and innovation.&lt;/p&gt;
&lt;p&gt;Being International Women&amp;rsquo;s Day, today we focus on women in tech.&lt;/p&gt;
&lt;h2 id="women-in-tech-stats-awareness"&gt;Women in Tech Stats Awareness&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Women earn an average of 17% (US) to 13% (EU) less than men&lt;/strong&gt;, according to &lt;a href="https://www.gao.gov/products/gao-23-106041"&gt;U.S. Census Bureau&lt;/a&gt; and &lt;a href="https://commission.europa.eu/strategy-and-policy/policies/justice-and-fundamental-rights/gender-equality/equal-pay/gender-pay-gap-situation-eu_en"&gt;European Commission&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;60% of women in tech said a parent or teacher encouraged them&lt;/strong&gt;. &lt;a href="https://www.logitech.com/en-us/mx/women-who-master.html#read-the-report"&gt;Logitech and Girls Who Code&amp;rsquo;s report&lt;/a&gt; on understanding the barriers women face in tech noted the importance of having role models and people encouraging them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In small companies, 30.2% of employees are women&lt;/strong&gt;, according to the &lt;a href="https://anitab.org/research-and-impact/top-companies/2020-results/"&gt;report Top Companies for Women Technologists&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;75% of women in tech are asked to handle more administrative tasks&lt;/strong&gt; compared to their male colleagues, according to &lt;a href="https://www.navisite.com/wp-content/uploads/2022/04/Gender-Divide-in-Tech-Infographic.pdf"&gt;Navisite&amp;rsquo;s survey&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below, you can meet some of Pulumi&amp;rsquo;s tech women - their experience, why they chose tech, and advice to thrive.&lt;/p&gt;
&lt;h2 id="pulumis-women-in-tech"&gt;Pulumi&amp;rsquo;s Women in Tech&lt;/h2&gt;
&lt;h3 id="sarah-hughes-software-engineer"&gt;Sarah Hughes, Software Engineer&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;I was lucky enough to go to high school with a ton of other girls who were into tech, so I took AP Computer Science in a class that was close to a 50/50 split. It really helped to start from scratch on equal footing. (Almost) everyone knew absolutely nothing, and it was obvious that our strengths and weaknesses were completely independent of gender.&amp;rdquo;&lt;/p&gt;
&lt;h3 id="lina-desloge-account-executive"&gt;Lina Desloge, Account Executive&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;I have always enjoyed problem-solving and working with people&amp;hellip;which is what ultimately led me to a technical product. The advice I would give my younger self is don&amp;rsquo;t worry, just start!&amp;rdquo;&lt;/p&gt;
&lt;h3 id="kelsey-dirks-customer-success-manager"&gt;Kelsey Dirks, Customer Success Manager&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;When I entered university, I chose Electrical Engineering as my major. I soon learned coding was not my specialty and switched to Communications, but I loved the people in the classes. It was clear both the professors and students were passionate about their craft. I knew that when I left university, I wanted to work with these types of people, but I had no idea in what capacity. Over the years, my experience led me to be a Customer Success Manager.&lt;/p&gt;
&lt;p&gt;What I would tell my younger self is to not stress about trying to figure everything out right away. Every job will have its ups and downs, but when it comes to a career, trust that it will all work out. The biggest piece of advice I can give to women entering the tech field is don’t be afraid to lean on your female support system. If you aren’t able to advocate for yourself, your sisters in STEM will.&amp;rdquo;&lt;/p&gt;
&lt;h3 id="jonelle-boyd-ux-designer"&gt;Jonelle Boyd, UX Designer&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;If I could give advice to women entering the tech field, I would tell them don’t be afraid of change. Whether that be a role change or a job change, because every new opportunity is a chance to learn and grow. I’ve changed roles as well as worked at a variety of different places during my career and I’ve learned something new in every position. There’s tremendous value in having a wide range of experience, so never be afraid of making that change.&amp;rdquo;&lt;/p&gt;
&lt;h3 id="casey-huang-software-engineer"&gt;Casey Huang, Software Engineer&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;To my younger self - At some point, you’ve heard people sell working in the tech industry by saying the hours are more flexible - you’re not chained to your desk 9 to 5, you can leave early as long as you get your work done. This is somewhat true, but you should know: there is always more work to do. Some of it is important enough to move the business needle. Some of it isn’t as important, but you just care a lot about it. It’ll be up to you to define your boundaries, and it will be up to you to defend them. But it’s okay; if your work environment is truly a good fit for you, they’ll follow your lead and support you. You can’t min/max life like you like to do in video games. What you’re doing is good enough. Don’t be so afraid of making mistakes. If anything, you’ll learn faster that way.&amp;rdquo;&lt;/p&gt;
&lt;h3 id="guinevere-saenger-software-engineer"&gt;Guinevere Saenger, Software Engineer&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;Working in tech provides me with significant financial independence, professional respect, and a flexible work schedule. These are worthwhile for anyone to have, but especially so for women.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re always looking for more amazing talent to &lt;a href="https://www.pulumi.com/community"&gt;join us in our community&lt;/a&gt; and as &lt;a href="https://www.pulumi.com/careers"&gt;part of the Pulumi team&lt;/a&gt;.&lt;/p&gt;</description><author>Sara Huddleston</author><category>pulumi-culture</category><category>community</category></item><item><title>Announcing KubeCrash Fall 2022 — the KubeCon Detroit Warm-up</title><link>https://www.pulumi.com/blog/announcing-kubecrash-fall-2022/</link><pubDate>Fri, 23 Sep 2022 10:19:23 -0500</pubDate><guid>https://www.pulumi.com/blog/announcing-kubecrash-fall-2022/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/announcing-kubecrash-fall-2022/index.png" /&gt;
&lt;p&gt;&lt;strong&gt;100% Virtual. 100% Free. 100% Open Source.&lt;/strong&gt; Arrive in style and up to date on the biggest trends for KubeCon + CloudNativeCon North America this October in Detroit, Michigan! KubeCrash is a fully-virtual two-day event curated by the coolest companies in cloud native, providing you with a practical, hands-on learning opportunity in the run-up to the conference. All for free! Held October 5 and 6 in both Americas and European time zones, you’ll emerge with new development skills and conversation starters for KubeCon. &lt;a href="https://www.kubecrash.io/"&gt;Take a peek at the program and register online!&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-importance-of-open-source"&gt;The Importance of Open Source&lt;/h2&gt;
&lt;p&gt;Your DevOps team drives the technology and tooling choices that build production. The benefits of open source mean that even in enterprise-grade environments, they increasingly choose an open-source tool over a closed-source option. Large communities of maintainers and other users, great documentation, and personalized support make open source an extremely appealing choice.&lt;/p&gt;
&lt;p&gt;This means that open source software has become the backbone of any modern tech stack. That rapidly-increasing reliance on open source means that any development team needs the skills to understand and effectively utilize these tools to remain on top. The KubeCrash event is tailor-made for this, with sessions and hands-on workshops for SREs, developers, platform engineers, and security engineers hosted by the maintainers of some of the most popular open source tools in the cloud native landscape.&lt;/p&gt;
&lt;h2 id="about-kubecrash"&gt;About KubeCrash&lt;/h2&gt;
&lt;p&gt;Our inaugural KubeCrash event, held alongside KubeCon + CloudNativeCon Europe, was a resounding success. This year, we’re making it even better with feedback from all of you!
KubeCrash Fall will be held before KubeCon, with two half-day events held in different timezones to accommodate everyone. You’ll be able to interact with speakers and other participants live, no matter where you are! One event will be held from 3pm to 6pm Central European Time, and the next will be held from 9am to 12pm US Pacific Time.
KubeCrash is a collaborative effort by seven different open source companies in the cloud native space, all of us coming together to bring you high-quality crash courses on cloud native technologies before KubeCon. We aren’t here to sell you anything or make you sit through pitches; you’ll get content on Pulumi, and also other cool open source projects like Goldilocks, cert-manager, Linkerd, CockroachDB, and Polaris. &lt;a href="https://www.kubecrash.io/past-events"&gt;Check out our last event for an idea of what you’ll see!&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-kubecrash-program"&gt;The KubeCrash Program&lt;/h2&gt;
&lt;p&gt;Show up ready to learn straight from the people who build and maintain the most popular and critical tooling in the ecosystem. From keynotes by Cheryl Hung to overviews of CNCF projects by their maintainers, to hands-on workshops and an end-user case study, there’s something for you no matter where you are in your cloud native journey.&lt;/p&gt;
&lt;h3 id="day-1-wednesday-october-5-european-and-east-americas-friendly-timezone"&gt;Day 1: Wednesday, October 5 (European and East Americas-friendly timezone)&lt;/h3&gt;
&lt;h4 id="3-to-6-pm-cet--9-am-to-12-pm-est--8-to-11-am-cst"&gt;3 to 6 pm CET | 9 am to 12 pm EST | 8 to 11 am CST&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Keynote&lt;/strong&gt;: to be announced&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lighting talk: Intro to the CNCF Cloud Native Maturity Model&lt;/strong&gt; by Danielle Cook, Co-chair CNCF Cartografos Group&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Whose cert is it anyway? How to build TLS trust using cert-manager&lt;/strong&gt; by Ashley Davis, cert-manager team&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Going Straight to the Edge&lt;/strong&gt; by Dinesh Majrekar and Mark Boost, founders of Civo
Emissary-ingress session&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hands-on workshop: Service mesh observability with Linkerd&lt;/strong&gt; by Flynn, Linkerd team and Emissary-ingress maintainer&lt;/p&gt;
&lt;h3 id="day-2-thursday-october-6-americas-friendly-timezone"&gt;Day 2: Thursday, October 6 (Americas-friendly timezone)&lt;/h3&gt;
&lt;h4 id="12-to-3-pm-est--11-am-to-2-pm-cst--9-am-to-12-pm-pst"&gt;12 to 3 pm EST | 11 am to 2 pm CST | 9 am to 12 pm PST&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Keynote&lt;/strong&gt;: TBS by Cheryl Hung, Engineering Manager, Apple&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lighting talk: The CNCF Cloud Native Glossary: Trusted. Simple. Community-driven&lt;/strong&gt; by Catherine Paganini, Cloud Native Glossary Maintainer&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Getting Started with Kubernetes Guardrails with Polaris&lt;/strong&gt; by Andy Suderman Creator and Maintainer of Goldilocks and Stevie Caldwell, Creator of GoNoGo&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hands-on Workshop with Aaron Friel of Pulumi: Program the Cloud with Six Pearls in Six Languages&lt;/strong&gt; using Pulumi&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kubecrash.io/program"&gt;Check out the program page for more details.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="join-us-on-october-5-and-6"&gt;Join us on October 5 and 6&lt;/h2&gt;
&lt;p&gt;Join us on October 5 and 6 for a specifically curated set of sessions, each led by a project maintainer, from projects covering modern cloud native security to improving the developer experience. It will be live, interactive, and fun. &lt;a href="https://www.kubecrash.io/"&gt;Register today!&lt;/a&gt;&lt;/p&gt;</description><author>Kat Cosgrove</author><category>kubecrash</category><category>events</category></item><item><title>Teaming up to help deliver more meals to Ukraine</title><link>https://www.pulumi.com/blog/meals-for-ukraine/</link><pubDate>Mon, 16 May 2022 09:00:54 +0200</pubDate><guid>https://www.pulumi.com/blog/meals-for-ukraine/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/meals-for-ukraine/index.png" /&gt;
&lt;p&gt;Why not do good while learning about cloud native tech? &lt;a href="https://buoyant.io/"&gt;Buoyant&lt;/a&gt;, &lt;a href="https://www.civo.com/"&gt;Civo&lt;/a&gt;, &lt;a href="https://www.cockroachlabs.com/"&gt;Cockroach Labs&lt;/a&gt;, &lt;a href="https://www.fairwinds.com/"&gt;Fairwinds&lt;/a&gt;, &lt;a href="https://www.pulumi.com/"&gt;Pulumi&lt;/a&gt;, and &lt;a href="https://www.jetstack.io/"&gt;Jetstack&lt;/a&gt; have teamed up to donate $2 for each virtual booth visitor to &lt;a href="https://wck.org/"&gt;World Central Kitchen&lt;/a&gt; (WCK), a non-profit committed to providing meals in response to humanitarian crises.&lt;/p&gt;
&lt;p&gt;Working with restaurants across Ukraine and in six countries welcoming refugees, WCK is providing hundreds of thousands of daily meals for people in need. WCK serves meals at shelters, hospitals, transit hubs, and more. It&amp;rsquo;s a wonderful mission and, if you agree, we encourage you to &lt;a href="https://donate.wck.org/give/398293#!/donation/checkout"&gt;donate to WCK directly&lt;/a&gt; 💙 🇺🇦 💛&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt;
&lt;p&gt;Participating is easy. If you registered for KubeCon, just click on the booth links below to visit our virtual booths. Each visit will count as a $2 donation, so if you visit us all, that&amp;rsquo;s $12 for the cause right there!&lt;/p&gt;
&lt;p&gt;Of course, there are many more reasons to visit our booths. You&amp;rsquo;ll find lots of great cloud native resources including demos, tutorials, ebooks, and more. Here are some of the highlights you can expect at each booth.&lt;/p&gt;
&lt;h3 id="pulumi--universal-infrastructure-as-code"&gt;Pulumi — Universal Infrastructure as Code&lt;/h3&gt;
&lt;p&gt;At the &lt;a href="https://www.pulumi.com/"&gt;Pulumi&lt;/a&gt; booth, you&amp;rsquo;ll learn about our cloud engineering platform, which brings infrastructure, developer, and security teams together through a unified software engineering process that tames cloud complexity and accelerates innovation. Don&amp;rsquo;t miss our Ask an Expert live sessions to hear directly from the engineering team. Whether you want to know more about how to build with Universal Infrastructure as Code in general-purpose programming and markup languages or just learn more about what&amp;rsquo;s on the roadmap, this is your chance to ask us anything.&lt;/p&gt;
&lt;h3 id="buoyant--the-creator-of-linkerd"&gt;Buoyant — the creator of Linkerd&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://buoyant.io/"&gt;Buoyant&lt;/a&gt; is announcing something really exciting: the introduction of &lt;em&gt;fully managed Linkerd&lt;/em&gt;. You can be one of the first to check out the demo, and you&amp;rsquo;ll also find a ton of service mesh content including a service mesh 101 in English and Spanish, their Engineer&amp;rsquo;s Guide to mTLS, and details on Buoyant&amp;rsquo;s Service Mesh Academy.&lt;/p&gt;
&lt;h3 id="civo--fast-simple-managed-kubernetes"&gt;Civo — Fast Simple, Managed Kubernetes&lt;/h3&gt;
&lt;p&gt;Stop by the &lt;a href="https://www.civo.com/"&gt;Civo&lt;/a&gt; booth for live sessions on how to get the most out of your Kubernetes environment - including demos, Civo marketplace walkthroughs and an inside look at how they live-provision a private region. You&amp;rsquo;ll find lots of resources and friendly team members to answer any questions on Civo’s easy-to-use managed Kubernetes service. It is fully CNCF certified and 100% Kubernetes upstream compatible.&lt;/p&gt;
&lt;h3 id="cockroach-labs--build-what-you-dream"&gt;Cockroach Labs — Build What you Dream&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.cockroachlabs.com/"&gt;CockroachDB&lt;/a&gt;&amp;rsquo;s presence this year at KubeCon (both physical and virtual) is primarily a charitable one (if you attend in person, visit booth P16, where for each badge scanned they&amp;rsquo;ll donate $3 to either Black Girls Code, Women Who Code, the Cancer Research Institute, or UNICEF for Ukrainian relief). Visit their booth to see demos and architecture overviews that relate what they’ve learned from building a multi-region, managed distributed SQL database offering on Kubernetes.&lt;/p&gt;
&lt;h3 id="fairwinds--kubernetes-governance-and-security"&gt;Fairwinds — Kubernetes Governance and Security&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.fairwinds.com"&gt;Fairwinds&lt;/a&gt;, a leader in Kubernetes governance providing a unified view between dev, sec, and ops, offers lots of great resources at their virtual booth this KubeCon. You can get a quick tour of Fairwinds Insights, learn about Kubernetes cost savings, how to make Kubernetes service ownership possible, typical Kubernetes security mistakes and much more. Come chat with a friendly Fairwinds engineer to talk about the many great open source solutions including Polaris, Goldilocks, Nova, and Pluto. Visit the &lt;a href="https://www.fairwinds.com/"&gt;Fairwinds&lt;/a&gt; booth today!&lt;/p&gt;
&lt;h3 id="jetstack--the-creator-of-cert-manager"&gt;Jetstack — the creator of cert-manager&lt;/h3&gt;
&lt;p&gt;Get more out of &lt;a href="https://cert-manager.io/"&gt;cert-manager&lt;/a&gt; and find out how &lt;a href="https://www.jetstack.io/"&gt;Jetstack&lt;/a&gt; Secure can eliminate workload misconfigurations and provide full visibility of each certificate across every production cluster. Chat directly to one of the project maintainers and learn to use cert-manager to secure Ingress endpoints and internal workloads using mTLS.&lt;/p&gt;
&lt;h2 id="lots-of-great-reasons-to-visit-our-booths"&gt;Lots of great reasons to visit our booths&lt;/h2&gt;
&lt;p&gt;There are plenty of good reasons to check out the great content of these amazing companies while supporting a wonderful charity that is doing an incredible job at helping the people of Ukraine.&lt;/p&gt;</description><author>Wendy Smith</author><category>community</category><category>pulumi-events</category></item><item><title>Introducing the Puluminaries</title><link>https://www.pulumi.com/blog/introducing-the-puluminaries/</link><pubDate>Tue, 03 May 2022 10:04:47 -0500</pubDate><guid>https://www.pulumi.com/blog/introducing-the-puluminaries/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/introducing-the-puluminaries/index.png" /&gt;
&lt;p&gt;Pulumi is more than a way to build, deploy, and manage your infrastructure and cloud applications. Pulumi is also a strong and vibrant community. We are very excited to announce and showcase our new program of community champions, the Puluminaries!&lt;/p&gt;
&lt;img src="puluminaries.png" width="500" height="500" alt="Puluminaries logo"/&gt;
&lt;p&gt;The Puluminaries program was created to recognize members of the Pulumi community who are experts and leaders in the field of programming and infrastructure, but also who give back to the community to make it grow! They help others get started, give feedback to make Pulumi&amp;rsquo;s roadmap even better, and educate people through content or public speaking. The program is open to all members of the community, and we welcome anyone to join the program.&lt;/p&gt;
&lt;p&gt;While the Puluminaries themselves have been active in the community for quite some time, we officially launched the program at &lt;a href="https://pulumi.com/pulumi-up"&gt;PulumiUP&lt;/a&gt; in 2022, and it is our pleasure to introduce the first cohort of members to the program!&lt;/p&gt;
&lt;h2 id="meet-the-puluminaries"&gt;Meet The Puluminaries!&lt;/h2&gt;
&lt;h3 id="engin-diri"&gt;Engin Diri&lt;/h3&gt;
&lt;img src="engin-diri.png" width="200" height="200" alt="Engin Diri"/&gt;
&lt;a data-track="twitter" href="https://twitter.com/_ediri"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-x"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="github" href="https://github.com/dirien"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Engin&amp;rsquo;s excitement for Pulumi is not possible to be measured using current science. He will always share his thoughts on new developments in the Pulumi project, as well as join in for fun and discussion in various PulumiVision livestreams!&lt;/p&gt;
&lt;h3 id="joshua-studt"&gt;Joshua Studt&lt;/h3&gt;
&lt;img src="joshua-studt.png" width="200" height="200" alt="Joshua Studt"/&gt;
&lt;a data-track="github" href="https://github.com/orionstudt"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Joshua is a longtime member of the Pulumi community, and he contributed to the implementation of Automation API for C#.&lt;/p&gt;
&lt;h3 id="kat-morgan"&gt;Kat Morgan&lt;/h3&gt;
&lt;img src="kat-morgan.png" width="200" height="200" alt="Kat Morgan"/&gt;
&lt;a data-track="twitter" href="https://twitter.com/usrbinkat"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-x"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="github" href="https://github.com/usrbinkat"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="linkedin" href="https://linkedin.com/in/usrbinkat"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-linkedin"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Kat has been a helpful member of the Pulumi community - not only providing feedback on real-world use of Pulumi, but also sharing her knowledge with &lt;a href="https://konghq.com/webinars/devmyops-deploy-kong-with-pulumi?utm_souce=pulumi&amp;amp;utm_medium=pulumi"&gt;workshops and webinars&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="komal-ali"&gt;Komal Ali&lt;/h3&gt;
&lt;img src="komal-ali.png" width="200" height="200" alt="Komal Ali"/&gt;
&lt;a data-track="twitter" href="https://twitter.com/zwitkali"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-x"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="github" href="https://github.com/komalali"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="linkedin" href="https://linkedin.com/in/komal-ali"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-linkedin"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;In addition to being a Puluminary, Komal is also a Pulumni, having spent time working to make Pulumi a better tool for developers - they were ever-present in making our Python SDK better and creating the &lt;a href="https://www.pulumi.com/docs/using-pulumi/automation-api/"&gt;Automation API&lt;/a&gt;!&lt;/p&gt;
&lt;h3 id="paul-hicks"&gt;Paul Hicks&lt;/h3&gt;
&lt;img src="paul-hicks.png" width="200" height="200" alt="Paul Hicks"/&gt;
&lt;a data-track="github" href="https://github.com/tenwit"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Paul seems to have an answer to everything. He is ever-present in the Pulumi Community, sharing his knowledge to folks who are just getting started, but also bringing to bear his real-world expertise in complex Pulumi implementations. Chances are, if you see a great answer to a question in &lt;a href="https://slack.pulumi.com/"&gt;Pulumi Community Slack&lt;/a&gt;, it came from Paul.&lt;/p&gt;
&lt;h3 id="ringo-de-smet"&gt;Ringo De Smet&lt;/h3&gt;
&lt;img src="ringo-smet.png" width="200" height="200" alt="Ringo De Smet"/&gt;
&lt;a data-track="twitter" href="https://twitter.com/ringods"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-x"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="github" href="https://github.com/ringods"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Ringo is one of the founding board members of &lt;a href="https://www.pulumi.com/blog/2022-03-30-introducing-pulumiverse/"&gt;the Pulumiverse&lt;/a&gt; - a place to interact and collaborate on Pulumi-based libraries, projects, and educational materials. Ringo (along with fellow Puluminary Simen A. W. Olsen) have brought their vision for expanding the Pulumi community to life with the creating of this community-operated space! Ringo also created the &lt;a href="https://github.com/ringods/pulumi-resource"&gt;Pulumi Resource Type for Concourse&lt;/a&gt;, and is ever-present in every community he is a part of, not just Pulumi&amp;rsquo;s!&lt;/p&gt;
&lt;h3 id="rizel-scarlett"&gt;Rizel Scarlett&lt;/h3&gt;
&lt;img src="rizel-scarlett.png" width="200" height="200" alt="Rizel Scarlett"/&gt;
&lt;a data-track="twitter" href="https://twitter.com/blackgirlbytes"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-x"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="github" href="https://github.com/blackgirlbytes"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;&amp;nbsp;&lt;a data-track="linkedin" href="https://www.linkedin.com/in/rizel-bobb-semple/"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-linkedin"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Rizel brings her remarkable talent for guidance and teaching to the Pulumi community. She has participated in many Pulumi events, including Cloud Engineering Summit, and &lt;a href="https://youtu.be/2uQEIYuJBZ4"&gt;appearing on the PulumiVision livestream&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="simen-a-w-olsen"&gt;Simen A. W. Olsen&lt;/h3&gt;
&lt;img src="simen-olsen.png" width="200" height="200" alt="Simen W Olsen"/&gt;
&lt;a data-track="github" href="https://github.com/cobraz"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#b-github"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;p&gt;Another one of the founding board members of &lt;a href="https://www.pulumi.com/blog/2022-03-30-introducing-pulumiverse/"&gt;the Pulumiverse&lt;/a&gt;, Simen has a great passion for technology communities, but especially for the Pulumi community. Simen was instrumental on the &lt;a href="https://github.com/pulumi/actions"&gt;Pulumi GitHub Action&lt;/a&gt; rewrite - designing and rearchitecting it in his free time.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Do you know someone who would make a great Puluminary? Let us know! You can email us at da@pulumi.com with your nominations!&lt;/em&gt;&lt;/p&gt;</description><author>Matty Stratton</author><category>community</category></item><item><title>PulumiUP Workshop Series</title><link>https://www.pulumi.com/blog/pulumiup-workshop-series/</link><pubDate>Tue, 03 May 2022 08:46:08 -0500</pubDate><guid>https://www.pulumi.com/blog/pulumiup-workshop-series/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumiup-workshop-series/index.png" /&gt;
&lt;p&gt;At Pulumi, we’re incredibly fortunate to have over 70 integration partners in our ecosystem – helping shared end-users to build, deploy and manage practically any cloud service they can imagine. Our most popular content often includes workshops that show end-users how to use these powerful integrations. This year for PulumiUP, we’re excited to announce that we’ve teamed up with a number of partners to deliver a workshop track that provides hands-on labs and demonstrations for a variety of platforms and scenarios.&lt;/p&gt;
&lt;h3 id="introduction-to-infrastructure-as-code"&gt;Introduction to Infrastructure as Code&lt;/h3&gt;
&lt;p&gt;Thursday, May 5th at 2:30 PM PDT&lt;/p&gt;
&lt;p&gt;We’ll explain the basics of IaC by exploring how to use Pulumi to build, configure and deploy a real-life, modern application using Docker.&lt;/p&gt;
&lt;h3 id="from-zero-to-production-in-kubernetes"&gt;From Zero to Production in Kubernetes&lt;/h3&gt;
&lt;p&gt;Tuesday, May 10th at 9:00 AM PDT&lt;/p&gt;
&lt;p&gt;Our friends from NGINX will show you how to leverage the power of Python with Pulumi to define and manage your Kubernetes deployments and build powerful abstractions that make getting to production easier than ever before. You’ll learn about the new open-source Modern Application Reference Architecture (MARA) that helps you quickly deploy an app platform that includes Amazon EKS, NGINX Kubernetes ingress controller, logstore, logagent, cert-manager, Prometheus, Grafana, and more.&lt;/p&gt;
&lt;h3 id="kubecrash"&gt;Kubecrash&lt;/h3&gt;
&lt;p&gt;Tuesday, May 17th at 9:00 AM PDT&lt;/p&gt;
&lt;p&gt;Join Pulumi and the maintainers of Linkerd, cert-manager, and other projects for a series of crash courses about Kubernetes and cloud-native, open source technologies.&lt;/p&gt;
&lt;h3 id="getting-started-with-azure-and-infrastructure-as-code"&gt;Getting Started with Azure and Infrastructure as Code&lt;/h3&gt;
&lt;p&gt;Wednesday, June 1st at 9:00 AM PDT&lt;/p&gt;
&lt;p&gt;In this workshop, you will use Pulumi&amp;rsquo;s Azure Native Provider, built directly from the Azure API, to provision infrastructure with Pulumi&amp;rsquo;s Typescript SDK. Join Microsoft Sr. Cloud Advocate, April Edwards, and Pulumi Developer Advocate Matty Stratton for this introduction to IaC.&lt;/p&gt;
&lt;h3 id="end-to-end-infrastructure-apps-and-auth-with-auth0"&gt;End-To-End Infrastructure, Apps, and Auth with Auth0&lt;/h3&gt;
&lt;p&gt;Tuesday, June 7th at 4:00 PM PDT&lt;/p&gt;
&lt;p&gt;In this live-coding session, Pulumi and Auth0 will walk through the process of building a three-tier web app: a single-page app built with React, a back end consisting of a REST API managed with Express and MongoDB. Finally, we&amp;rsquo;ll show you how to enable authentication to restrict access to your app.&lt;/p&gt;
&lt;h3 id="aws-immersion-day-hands-on-infrastructure-as-code"&gt;AWS Immersion Day: Hands-On Infrastructure as Code&lt;/h3&gt;
&lt;p&gt;Tuesday, June 14th at 9:00 AM PDT&lt;/p&gt;
&lt;p&gt;Pulumi and friends from VirtusLab and AWS have planned an interactive session to introduce IaC concepts using familiar programming languages to provision modern cloud infrastructure. This session will focus on new Pulumi capabilities.&lt;/p&gt;
&lt;h3 id="gitops-with-github-actions-and-the-pulumi-operator"&gt;GitOps with GitHub Actions and the Pulumi Operator&lt;/h3&gt;
&lt;p&gt;Tuesday, June 21st at 9:00 AM PDT&lt;/p&gt;
&lt;p&gt;Combining GitHub Actions with the Pulumi Kubernetes Operator helps you to implement powerful GitOps workflows and automation for both your infrastructure and workloads. We’ve partnered with the GitHub team to deliver step-by-step labs to help you to get started with GitOps.&lt;/p&gt;
&lt;h3 id="cicd-pipelines-for-kubernetes-apps-with-pulumi--codefresh"&gt;CI/CD Pipelines for Kubernetes Apps with Pulumi &amp;amp; Codefresh&lt;/h3&gt;
&lt;p&gt;Wednesday, June 22nd at 9:30 AM PDT&lt;/p&gt;
&lt;p&gt;The Codefresh team will help you to learn the basics of CI/CD and how to declare cloud resources and set up a simple pipeline for Kubernetes deployments using your favorite programming languages with Pulumi and Codefresh.&lt;/p&gt;
&lt;h3 id="deploying-microservices-with-aws-lambda-and-pulumi"&gt;Deploying Microservices with AWS Lambda and Pulumi&lt;/h3&gt;
&lt;p&gt;Tuesday, June 28, 12:00 PM PDT&lt;/p&gt;
&lt;p&gt;In this workshop, we’ll examine how Pulumi can rapidly accelerate provisioning of cloud infrastructure. We’ll focus on AWS Lambda and build an example set of microservices utilizing AWS’s newest Lambda features. Matty Stratton (Pulumi) and Marina Novikova (AWS) will guide you through the process of provisioning a set of example Lambda resources in AWS.&lt;/p&gt;
&lt;h3 id="getting-started-with-infrastructure-as-code-on-oracle-cloud"&gt;Getting Started with Infrastructure as Code on Oracle Cloud&lt;/h3&gt;
&lt;p&gt;Thursday, July 14th at 9:00 AM PDT
&lt;a href="https://go.oracle.com/LP=127531?elqCampaignId=350230" target="_blank" rel="noopener noreferrer"&gt;Register&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that we have a brand new integration with &lt;a href="https://www.pulumi.com/registry/packages/oci"&gt;Oracle Cloud Infrastructure (OCI)&lt;/a&gt; the team is preparing a new workshop to help you to get the most out of the new provider. Laura Santamaria (Pulumi) and Gaurav Jain (Oracle) will show you how to define, deploy and manage OCI resources using your favorite programming languages.&lt;/p&gt;
&lt;h3 id="getting-started-with-infrastructure-as-code-on-digitalocean"&gt;Getting started with Infrastructure as Code on DigitalOcean&lt;/h3&gt;
&lt;p&gt;Thursday, July 28th at 8:00 AM PDT
&lt;a href="https://www.pulumi.com/resources/getting-started-with-infrastructure-as-code-on-digital-ocean"&gt;Register&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this hands-on workshop, Matty Stratton (Pulumi) and Chris Sevilleaja (DigitalOcean) will show you how to stand up basic services using Infrastructure as Code with hands-on labs using JavaScript/TypeScript.&lt;/p&gt;</description><author>Matty Stratton</author><author>Isaac Harris</author><category>pulumi-up</category><category>workshop</category></item><item><title>Announcing Pulumi Community Slack Archive</title><link>https://www.pulumi.com/blog/announcing-community-slack-archive/</link><pubDate>Mon, 02 May 2022 12:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/announcing-community-slack-archive/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/announcing-community-slack-archive/index.png" /&gt;
&lt;p&gt;Creating a place for the Pulumi community to gather, ask questions, get help in real-time, and share successes has been an important part of the explosive growth we&amp;rsquo;ve seen in both users and customers. The Pulumi community slack has grown to over 7000 members and well over 200,000 messages.&lt;/p&gt;
&lt;p&gt;Within those 200,000 messages are years of information kept behind a &amp;ldquo;walled garden&amp;rdquo; that is undiscoverable outside Slack&amp;rsquo;s search capabilities.&lt;/p&gt;
&lt;p&gt;Today we&amp;rsquo;re announcing that our community slack is now publicly available via &lt;a href="https://archive.pulumi.com"&gt;https://archive.pulumi.com&lt;/a&gt; thanks to &lt;a href="https://linen.dev"&gt;Linen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For many, Slack has become the de-facto collaboration tool. Adding Slack workspaces is relatively straightforward and means you can communicate with various different communities and your colleagues in real-time.&lt;/p&gt;
&lt;p&gt;This ability to use the tools you&amp;rsquo;re using in your everyday work to also quickly get help with Pulumi has proven to be extremely successful. Our users often tell us that having access to Pulumi staff and other community members helps them accelerate their cloud engineering journey. In addition to providing value to our users, the Pulumi team enjoys having a mechanism to engage with users to get feedback and inform them about the Pulumi ecosystem. It&amp;rsquo;s clear to us that the Pulumi community slack has proven invaluable as Pulumi has grown.&lt;/p&gt;
&lt;p&gt;The use of Slack for our community meeting place isn&amp;rsquo;t without its problems. Often, the first port of call for users that need answers is to use search engines, and all of the information stored in Slack isn&amp;rsquo;t readily available by default with Slack. The Pulumi team regularly answers questions on &lt;a href="https://stackoverflow.com/questions/tagged/pulumi"&gt;StackOverflow&lt;/a&gt; and via &lt;a href="https://github.com/pulumi/pulumi/discussions"&gt;GitHub Discussions&lt;/a&gt; which are searchable and indexed by search engines, but adding the treasure trove of information from Slack will improve the experience for eager Pulumi users.&lt;/p&gt;
&lt;p&gt;Until now, this has been exceptionally difficult. With the recent launch of &lt;a href="https://linen.dev"&gt;Linen&lt;/a&gt; we are able to bring our community chat outside of Slack&amp;rsquo;s boundaries in an easily searchable, indexable way.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re excited to provide this to the community and encourage you to try it out at &lt;a href="https://archive.pulumi.com"&gt;https://archive.pulumi.com&lt;/a&gt;.&lt;/p&gt;</description><author>Lee Briggs</author><category>community</category></item><item><title>Introducing KubeCrash: Cloud Native Crash Courses</title><link>https://www.pulumi.com/blog/introducing-kubecrash/</link><pubDate>Fri, 08 Apr 2022 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/introducing-kubecrash/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/introducing-kubecrash/index.png" /&gt;
&lt;p&gt;Can’t make it to Valencia for KubeCon this year? Timezone doesn’t work for the virtual conference either? We can’t fix time, but if you’re feeling left out and still want some of that sweet cloud native content, you can still join us for &lt;a href="https://kubecrash.io/"&gt;KubeCrash&lt;/a&gt;, a new event hosting live crash courses and sessions on cloud native tech. Come hang out and learn directly from the maintainers of cloud native open source projects!&lt;/p&gt;
&lt;h2 id="about-kubecrash"&gt;About KubeCrash&lt;/h2&gt;
&lt;p&gt;Five open source companies have teamed up to bring you top-notch, KubeCon-grade crash courses on cloud native tech. No vendor pitches, just awesome open source content on projects such as Linkerd, cert-manager, CockroachDB, Pulumi, Polaris, and Goldilocks.&lt;/p&gt;
&lt;p&gt;With Kubernetes becoming the new standard for cloud-hosted application development, DevOps teams are driving the technology choices for enterprise-grade cloud native tooling. Freely available open source solutions are often the primary source for these tooling decisions.&lt;/p&gt;
&lt;p&gt;KubeCrash provides a half-day knowledge sharing and virtual learning environment for developers, reliability engineers, cloud security specialists, and platform engineers. Learn directly from the maintainers of some of the most popular open source projects in this series of focused talks and workshops.&lt;/p&gt;
&lt;h2 id="the-kubecrash-program"&gt;The KubeCrash program&lt;/h2&gt;
&lt;p&gt;Come prepared for a schedule packed with great content and actionable insights directly from the teams that maintain some of the ecosystem&amp;rsquo;s most popular open source projects. The program will cover the latest learnings on implementing scalable zero-trust, scanning workloads for improved cloud native security, using service mesh to ensure high availability across multi-cluster infrastructure, and delivering &amp;ldquo;serverless&amp;rdquo; for multi-cloud deployments.&lt;/p&gt;
&lt;h3 id="program-overview"&gt;Program overview&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Using cert-manager to enable zero-trust identities for intra-pod communication &amp;mdash; &lt;em&gt;Jake Sanders, cert-manager maintainer&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Modern cloud native architectures require the network to be considered untrustworthy and this is why internal workloads are rapidly driving the use of mTLS and private PKI. This workshop from Jetstack will demonstrate how to use cert-manager to issue, manage and rotate mTLS certs, allowing users to have strongly attested and verified Machine Identities between Kubernetes pods. All without the workload private keys leaving node memory! Think of this session as a precursor to implementing a service mesh solution, using cert-manager to establish zero trust environments, perhaps defined by trust domains, and enforce security for pod to pod traffic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Multi-cluster failover using Linkerd &amp;mdash; &lt;em&gt;Eliza Weisman, Linkerd maintainer&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Failover across clusters is a great way to improve the overall uptime and reliability of Kubernetes applications. While whole-cluster failover can be accomplished at the global ingress layer, failing over individual services is a little more difficult. During this session, Linkerd maintainer Eliza Weisman will walk you through how to use Linkerd, the CNCF graduated service mesh, to enable traffic failover for individual services across clusters. Attendees will learn how to combine service mesh metrics, traffic shifting, and cross-cluster communication in a cohesive and automated way using pure open source, while preserving fundamental security guarantees such as mutual TLS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Optimizing and Securing Kubernetes Workloads with Polaris and Goldilocks &amp;mdash; &lt;em&gt;Rachel Sweeney, Fairwinds and Andy Suderman, Polaris and Goldilocks maintainer&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Learn how to scan your Kubernetes workloads to improve your resource utilization and security using open source tools Polaris and Goldilocks. You will watch Andy Suderman, Director of R&amp;amp;D and Technology, and Rachel Sweeney, SRE at Fairwinds, as they show how to correctly configure your clusters based on Kubernetes&amp;rsquo; best practices for security and efficiency.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using Kubernetes to deliver a “serverless” service &amp;mdash; &lt;em&gt;Lisa-Marie Namphy and Jim Walker, Cockroach Labs&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this talk, Cockroach Labs team members will share how they leverage Kubernetes to deliver a &amp;ldquo;serverless&amp;rdquo; experience. Serverless promises to change the way we consume software. It allows us to potentially pay for what we use only and help drive down operational costs by minimizing resource consumption. Architecting for serverless requires a unique look at app logic and how it is deployed&amp;mdash;a combination of the logical and physical worlds. An architectural pattern has emerged where we can scale ephemeral compute separate from services that need to persist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Multi-cloud, single deploy: cloud engineering with Kubernetes and Pulumi &amp;mdash; &lt;em&gt;Aaron Friel and Guinevere Saenger, Pulumi&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Business constraints and customer requests often require to stand up new Kubernetes environments across multiple cloud providers. This growing complexity in computing infrastructure will incur greater operational costs for organizations when coordinating across multiple teams. Pulumi engineers Aaron Friel and Guinevere Saenger will demonstrate standing up Kubernetes clusters, deploying applications, and automating ops tasks by building a CLI using the Pulumi Automation API. These tools empower every engineer&amp;mdash;from application developers to site reliability engineers&amp;mdash;to be a cloud engineer.&lt;/p&gt;
&lt;h2 id="join-us-on-may-17"&gt;Join us on May 17&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re staying in the Americas (or are up for a late-night session) this KubeCon, join us on Tuesday, May 17th starting at 9 am PST/10 am CST/12 pm EST. Enjoy a specifically curated set of sessions, each led by a project maintainer from projects covering modern cloud native security to improving the developer experience. &lt;a href="https://www.kubecrash.io/"&gt;Register today&lt;/a&gt;!&lt;/p&gt;</description><author>Kat Cosgrove</author><category>cloud-native</category><category>announcements</category></item><item><title>Announcing PulumiUP 2022: The Cloud Awakens on May 4th</title><link>https://www.pulumi.com/blog/announcing-pulumi-up-2022/</link><pubDate>Thu, 31 Mar 2022 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/announcing-pulumi-up-2022/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/announcing-pulumi-up-2022/index.png" /&gt;
&lt;p&gt;Calling all cloud engineers! Today we announce the second annual &lt;a href="https://www.pulumi.com/pulumi-up/"&gt;PulumiUP&lt;/a&gt; virtual conference taking place on May 4, 2022. We will also host the inaugural Pulumi Community Summit on May 5 to virtually assemble the world’s cloud, infrastructure, and Pulumi practitioners of all experience levels (hint: that’s you&amp;mdash;all are welcome)! &lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Register for both events here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We’ve worked hard to curate a half-day of learning and expert insights from the people that are forming the best practices of the modern cloud and cloud native infrastructure era. On May 4, join us for four hours of exciting Pulumi product news and demos, technical talks, case studies of modern cloud innovators, and conversations on cloud topics that you won’t hear anywhere else. Hear from Pulumi’s CEO and CTO, pioneering engineers and engineering leaders from different industries, and Pulumi’s engineers. We are also introducing two tracks designed for Practitioners and Engineering Leaders.&lt;/p&gt;
&lt;h2 id="whos-speaking-at-pulumiup-2022"&gt;Who’s speaking at PulumiUP 2022?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Aaron Friel, Staff Software Engineer, Pulumi&lt;/li&gt;
&lt;li&gt;Elad Ben-Israel, Principal Software Development Engineer, Amazon Web Services&lt;/li&gt;
&lt;li&gt;Joe Duffy, CEO &amp;amp; Founder, Pulumi&lt;/li&gt;
&lt;li&gt;Justin Fitzhugh, VP of Cloud Engineering, Snowflake&lt;/li&gt;
&lt;li&gt;Kat Cosgrove, Staff Developer Advocate, Pulumi&lt;/li&gt;
&lt;li&gt;Luke Hoban, CTO, Pulumi&lt;/li&gt;
&lt;li&gt;Meagan Cojocar, Senior Product Manager, Pulumi&lt;/li&gt;
&lt;li&gt;Tomas Jansson, Software Architect, Elkjøp Nordic AS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the coming weeks, we will be announcing even more speakers. Stay tuned!&lt;/p&gt;
&lt;h2 id="whats-in-store-at-pulumiup-2022"&gt;What’s in store at PulumiUP 2022?&lt;/h2&gt;
&lt;p&gt;Stay tuned as we will announce the full agenda and speakers soon on our website and in an email to registrants. Here’s what you can expect at this year’s event:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keynotes&lt;/strong&gt;: Hear from Pulumi leaders Joe Duffy (Founder &amp;amp; CEO) and Luke Hoban (CTO) as they share new product announcements, demos, and thoughts on trends in the modern cloud.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Technical Talks&lt;/strong&gt;: Dive deep with Pulumi’s engineers and guest speakers from the industry to learn best practices for infrastructure as code with popular programming languages and see demos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case Studies&lt;/strong&gt;: Learn from engineers and leaders about how they have accelerated development velocity and increased reliability for their modern cloud applications with Pulumi.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expert Conversations&lt;/strong&gt;: Listen in on lively debates and discussions about the intersection of software development and cloud infrastructure from panels made up of industry leaders and practitioners.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two Tracks&lt;/strong&gt;: Choose from two session tracks that are designed for Practitioners and Engineering Leaders, in addition to the keynote and main stage presentations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inaugural Community Summit&lt;/strong&gt;: Connect and engage with Pulumi practitioners from around the world&amp;mdash;from the comfort of your home. We are hosting a Community Summit on May 5 featuring lightning talks and discussions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Workshops&lt;/strong&gt;: Get hands-on with Pulumi and cloud engineering in 1-hour workshops that will cover the fundamentals of Infrastructure as Code as well as more advanced subjects for experienced Pulumi users.&lt;/p&gt;
&lt;h2 id="join-us-on-may-4-and-5"&gt;Join us on May 4 and 5&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Register for PulumiUP and the Community Summit now&lt;/a&gt;! We will send you updates on the final agenda and speakers and post-event updates such as session recordings and upcoming events.&lt;/p&gt;</description><author>George Huang</author><category>pulumi-events</category></item><item><title>Introducing the Pulumiverse</title><link>https://www.pulumi.com/blog/2022-03-30-introducing-pulumiverse/</link><pubDate>Wed, 30 Mar 2022 10:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/2022-03-30-introducing-pulumiverse/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/2022-03-30-introducing-pulumiverse/index.png" /&gt;
&lt;p&gt;Today, we&amp;rsquo;re excited to announce that we&amp;rsquo;re working with the Pulumi community to provide a place to interact and collaborate on Pulumi-based libraries, projects, and educational materials: the &lt;a href="https://github.com/pulumiverse"&gt;Pulumiverse&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This project is especially important to me, because it&amp;rsquo;s an idea that I&amp;rsquo;ve tried in the past, 2018 😯, and failed to commit to and give it the attention it deserves.&lt;/p&gt;
&lt;p&gt;Fortunately, two other wonderful Pulumi community members stepped up and started to put together their own programme and with me now being at Pulumi, the timing was amazingly serendipitous.&lt;/p&gt;
&lt;p&gt;I spoke with &lt;a href="https://twitter.com/ringods"&gt;Ringo De Smet&lt;/a&gt; and &lt;a href="https://twitter.com/cobrazo"&gt;Simen A. W. Olsen&lt;/a&gt;, the founding members of the Pulumiverse.&lt;/p&gt;
&lt;p&gt;Ringo, Head of CI/CD at Napoleon Games, had this to say about why he&amp;rsquo;s excited to create the Pulumiverse:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For infrastructure automation, we had other great tools which preceded Pulumi: Chef, Puppet, Ansible. Any of these tools have a vibrant community of people preventing that all of us need to re-invent the wheel. We had &lt;a href="https://sous-chefs.org"&gt;Sous-Chefs&lt;/a&gt; for Chef &amp;amp; &lt;a href="https://voxpupuli.org"&gt;Vox Pupuli&lt;/a&gt; for Puppet. But I see a lot of Pulumi users implementing the same stuff over and over again. That&amp;rsquo;s why I think Pulumi needs it&amp;rsquo;s own community. So I started it: &lt;a href="https://github.com/pulumiverse"&gt;Pulumiverse&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Simon, a Developer at &lt;a href="https://github.com/bjerkio"&gt;Bjerk AS&lt;/a&gt;, shared:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I imagine a community filled with like-minded people who build and support Pulumi providers, opinionated components, configurations and share ideas on how we can utilize the power of Pulumi in new ways. So I created Pulumiverse to share my enthusiasm, give back to Pulumi and support developers by building a platform where we can work together!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="what-is-the-pulumiverse"&gt;What is the Pulumiverse?&lt;/h2&gt;
&lt;p&gt;Pulumiverse, in the simplest form, is a GitHub organization. It provides a community-operated place for anyone to communicate, contribute, and collaborate with other members of the Pulumi community and build abstractions and SDKs that can be shared and used by anyone.&lt;/p&gt;
&lt;p&gt;There are many libraries or collections of components for Pulumi out there. Most of them are made based on requirements of individual companies and developers. Pulumiverse aims to make a community where these libraries can be created and where opinionated configurations for Pulumi resources can be stored and discussed.&lt;/p&gt;
&lt;h2 id="current-projects"&gt;Current Projects&lt;/h2&gt;
&lt;p&gt;The Pulumiverse launches with just a few projects, but we know that, with the support of such an amazing community, the Pulumiverse will grow and grow and provide invaluable resources for anyone who wants to build or use Pulumi for a library or project.&lt;/p&gt;
&lt;h3 id="awesome-pulumi"&gt;Awesome Pulumi&lt;/h3&gt;
&lt;p&gt;🐙 &lt;a href="https://github.com/pulumiverse/awesome-pulumi"&gt;Awesome Pulumi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Everybody loves an awesome list, and this one delivers to you a list of awesome Pulumi resources, books, tutorials, talks, and much more.&lt;/p&gt;
&lt;p&gt;Want your project listed? Open a PR. We can&amp;rsquo;t wait to share it with everyone.&lt;/p&gt;
&lt;h3 id="kubernetes-sdks"&gt;Kubernetes SDKs&lt;/h3&gt;
&lt;p&gt;🐙 &lt;a href="https://github.com/pulumiverse/kubernetes-sdks"&gt;Kubernetes SDKs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Kubernetes SDKs project aims to provide multi-language SDKs for interacting with Kubernetes Custom Resource Definitions (CRDs). Currently, it automatically builds SDKs for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ArgoCD&lt;/li&gt;
&lt;li&gt;CertManager&lt;/li&gt;
&lt;li&gt;Contour&lt;/li&gt;
&lt;li&gt;Crossplane&lt;/li&gt;
&lt;li&gt;Istio&lt;/li&gt;
&lt;li&gt;Kong Ingress&lt;/li&gt;
&lt;li&gt;Knative&lt;/li&gt;
&lt;li&gt;RedPanda&lt;/li&gt;
&lt;li&gt;Tyk&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is just the beginning, and we want to expand this collection quickly. So if you&amp;rsquo;re working with Kubernetes and want a rich developer experience for authoring custom resources, open an issue and let us know what you need.&lt;/p&gt;
&lt;h3 id="pulumi-concourse--unifi"&gt;Pulumi Concourse &amp;amp; Unifi&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumiverse/pulumi-concourse"&gt;Concourse Provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumiverse/pulumi-unifi"&gt;Unifi Provider&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are community-maintained providers and are examples of how you can share your providers with the world as part of the Pulumiverse.&lt;/p&gt;
&lt;h3 id="your-project"&gt;Your Project?&lt;/h3&gt;
&lt;p&gt;Got your own library that you think would be beneficial to the community?&lt;/p&gt;
&lt;p&gt;Join us in the #pulumiverse channel on the &lt;a href="https://pulumi.slack.com"&gt;Pulumi Slack&lt;/a&gt;, and we&amp;rsquo;ll be happy to help you get it over to the Pulumiverse.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll see you soon! 👋&lt;/p&gt;</description><author>David Flanagan</author><category>community</category></item><item><title>Migrating My Infrastructure From Terraform to Pulumi</title><link>https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/</link><pubDate>Tue, 22 Feb 2022 12:36:23 -0600</pubDate><guid>https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/migrating-my-infrastructure-from-terraform-to-pulumi/index.png" /&gt;
&lt;p&gt;Pulumi community member &lt;a href="https://blog.ekik.org/"&gt;Erik Näslund&lt;/a&gt; shares his thoughts on how to migrate from Terraform to Pulumi. Read on to learn all the details of his experience!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using &lt;a href="https://www.terraform.io/"&gt;Terraform&lt;/a&gt; for a couple of years and overall I&amp;rsquo;ve been quite happy with it. However there&amp;rsquo;s a few things that started to bother me more and more recently.&lt;/p&gt;
&lt;p&gt;Terraform uses a language called Hashicorp HCL to define the infrastructure. It&amp;rsquo;s a relatively simple declarative language, but it&amp;rsquo;s something I had to learn along the way. Just like any language it has it&amp;rsquo;s little quirks, and I often found myself spending more time than I wanted to figure out how to do certain things. As I&amp;rsquo;m doing all the infrastructure myself I really wanted to be able to use a language I&amp;rsquo;m familiar with, to make things simple.&lt;/p&gt;
&lt;p&gt;I had written my own &lt;a href="https://www.terraform.io/docs/language/modules/develop/index.html"&gt;Terraform modules&lt;/a&gt; to organize my code. Modules are a great help when it comes to organizing your code in a logical way, and I strongly recommend it if you haven&amp;rsquo;t tried using them already. However, after using it for a while I realized that the Terraform &lt;a href="https://www.terraform.io/docs/language/expressions/types.html"&gt;type system&lt;/a&gt; left something to be desired. There are a few basic types available, but not much more than that. This caused bad &amp;ldquo;micro interactions&amp;rdquo; between me and Terraform. It was commonplace for me to submit an MR to my Gitlab CI where I passed in a security group &lt;em&gt;name&lt;/em&gt; instead of an &lt;em&gt;arn&lt;/em&gt; or &lt;em&gt;id&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The third and perhaps most important point is that I think a custom language like HCL is the wrong way to go long term. Don&amp;rsquo;t get me wrong - I love the people at Hashicorp and I&amp;rsquo;m forever grateful for Terraform because it&amp;rsquo;s the first product that made me enjoy writing IaC. That being said, I think it&amp;rsquo;s a better choice to write libraries for existing languages, instead of trying to create a configuration language of your own. There&amp;rsquo;s a lot of constructs that I&amp;rsquo;m used to having in Python that I sorely miss having available in Terraform. In my opinion there&amp;rsquo;s no reason to develop your own configuration language since it&amp;rsquo;s a time consuming task, and I don&amp;rsquo;t find it better than a general purpose language anyways.&lt;/p&gt;
&lt;h3 id="why-did-i-choose-pulumi"&gt;Why did I choose Pulumi?&lt;/h3&gt;
&lt;p&gt;I have this thing called &amp;ldquo;Fun time Friday&amp;rdquo; where I spend the first half day on Fridays exploring new things I&amp;rsquo;ve heard about. Most of the things I look at during that time end up being scrapped, and there&amp;rsquo;s zero pressure to push things into production.&lt;/p&gt;
&lt;p&gt;However after exploring Pulumi I felt that it might be significantly better for me than Terraform. I decided to take a day to see if I could migrate my infrastructure.&lt;/p&gt;
&lt;p&gt;Could I have used something else, like &lt;a href="https://aws.amazon.com/cdk/"&gt;AWS CDK&lt;/a&gt;? I most probably could. The nice thing about running a company of one is that there&amp;rsquo;s no need for analysis paralysis! At this point I believed that Pulumi was a better choice for me than Terraform, so I went for it.&lt;/p&gt;
&lt;p&gt;Personally I struggle a bit with CDK being mostly Amazon-centric. I sometimes use my IaC to configure things outside of AWS as well. The other issue for me is that CDK by default uses AWS CloudFormation to provision resources. I&amp;rsquo;ve been bitten a few times by CF. Some times it&amp;rsquo;s been because of buggy behavior, e.g. a stack that refused to terminate. Other times it&amp;rsquo;s been the fact that CF often lags behind in capabilities, so it&amp;rsquo;s common to have to wait a few months for a new feature to be usable through CF.&lt;/p&gt;
&lt;p&gt;Sure, I could use &lt;a href="https://www.hashicorp.com/blog/cdk-for-terraform-enabling-python-and-typescript-support"&gt;CDK for Terraform&lt;/a&gt; to have CDK generate Terraform HCL for me. However, now we&amp;rsquo;re quickly getting away from the simple system I wanted in the first place.&lt;/p&gt;
&lt;p&gt;Apologies to those of you who are screaming &lt;em&gt;&amp;ldquo;FFS - CDK is the best thing ever!&amp;quot;&lt;/em&gt; at your monitors right now. You might be 100% right! From what I&amp;rsquo;ve seen CDK seems pretty awesome for the most part. I didn&amp;rsquo;t end up with Pulumi because CDK seemed bad. I ended up with Pulumi because it seemed like a slightly better fit for my needs :).&lt;/p&gt;
&lt;h3 id="pulumi-in-3-minutes"&gt;Pulumi in 3 minutes&lt;/h3&gt;
&lt;p&gt;You might already know a bit of Pulumi, but here&amp;rsquo;s a very quick overview plus some advice on where to go from here.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/resources.png" alt="image.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pulumi allows you to write your IaC using TypeScript, Javascript, Python, Go or C#.&lt;/li&gt;
&lt;li&gt;You define &lt;em&gt;resources&lt;/em&gt; which have &lt;em&gt;inputs&lt;/em&gt; and &lt;em&gt;outputs&lt;/em&gt;. As an example, a resource could be an RDS database Instance. One of it&amp;rsquo;s inputs would be the database version to use. One of the outputs would be the hostname / address of the server.&lt;/li&gt;
&lt;li&gt;The outputs are lazily evaluated, and their exact value is often not known until after you&amp;rsquo;ve executed your code. I.e. you wouldn&amp;rsquo;t have the &lt;code&gt;db_instance.address&lt;/code&gt; until the instance had been created. Think of outputs as promises / futures.&lt;/li&gt;
&lt;li&gt;You can use &lt;a href="https://www.pulumi.com/docs/concepts/resources/#components"&gt;component resources&lt;/a&gt; to group your resources into logical groups - similar to how Terraform modules work. If you don&amp;rsquo;t do this there&amp;rsquo;s a high risk you&amp;rsquo;ll end up with a very messy setup further down the line.&lt;/li&gt;
&lt;li&gt;Read Pulumi&amp;rsquo;s own &lt;a href="https://www.pulumi.com/docs/concepts/"&gt;overview&lt;/a&gt; and &lt;a href="https://www.pulumi.com/docs/concepts/resources/#autonaming"&gt;naming&lt;/a&gt; docs before attempting to use Pulumi yourself. I&amp;rsquo;d say that&amp;rsquo;s the most important bit to know about.&lt;/li&gt;
&lt;li&gt;Pulumi are using the &lt;a href="https://en.wikipedia.org/wiki/Open-core_model"&gt;open core&lt;/a&gt; model where most features are free, but some extra goodies are on a paid tier. You can use the open source version and do state management yourself, but you miss out on certain features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what does Pulumi code look like? Below is a minimal extract of some of the Python code I&amp;rsquo;ve written (slightly altered).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# __main__.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prod_redis_server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RedisServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;redis-prod&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;route53_zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;example_com_route53_zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;route53_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;redis-prod.example.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;security_groups&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;my_ecs_service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;task_security_group&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# components/redis_server.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RedisServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ComponentResource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;route53_zone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route53&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Route53 Zome where the DNS record will be created.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;route53_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Full DNS name of the CNAME record, e.g. &amp;#39;redis.example.com&amp;#39;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;security_groups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecurityGroup&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# Security groups which should be granted access to the server.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;vt:RedisServer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Prefix with `self.` if you want to access the security group from outside this component.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;security_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecurityGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ingress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecurityGroupIngressArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;from_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6379&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;to_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6379&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tcp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;security_groups&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;security_groups&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ResourceOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Create all the other sub resources needed.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see it&amp;rsquo;s really simple and clean for me to set up a Redis server now.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also the fact that I can use the Pulumi Console (web interface) to check the state of my infrastructure really quickly. I found myself doing this instead of logging in to the AWS console or using the AWS cli.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/image1.jpeg" alt="image.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/image2.jpeg" alt="image.png"&gt;&lt;/p&gt;
&lt;h3 id="how-i-went-about-the-migration"&gt;How I went about the migration&lt;/h3&gt;
&lt;p&gt;After reading the &lt;a href="https://www.pulumi.com/docs/iac/adopting-pulumi/migrating-to-pulumi/from-terraform/"&gt;migration guide&lt;/a&gt; I immediately tried out what seemed to be the obvious option - &lt;a href="https://www.pulumi.com/tf2pulumi/"&gt;tf2pulumi&lt;/a&gt;. This is supposed to be able to convert Terraform code directly to Pulumi. In my case it simply errored out and was not able to convert my Terraform code. To be fair my TF code was using slightly more &amp;ldquo;advanced&amp;rdquo; features like custom written modules, so it wasn&amp;rsquo;t the easiest thing to handle for tf2pulumi. I recommend you try it out, because it sounds great in theory. However it wasn&amp;rsquo;t an option for me, so I had to go for a more manual approach. In retrospect I&amp;rsquo;m actually quite happy I did, because it gave me the opportunity to organise my code in a way that I preferred.&lt;/p&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;As of Pulumi CLI v3.71.0, &lt;code&gt;tf2pulumi&lt;/code&gt; has been replaced with &lt;code&gt;pulumi convert --from terraform&lt;/code&gt;. &lt;a href="https://www.pulumi.com/blog/converting-full-terraform-programs-to-pulumi/"&gt;Converting Full Terraform Programs to Pulumi blog&lt;/a&gt; has more details.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Don&amp;rsquo;t worry though - &amp;ldquo;manual&amp;rdquo; imports using Pulumi is still rather easy to perform, albeit a bit time consuming. Here&amp;rsquo;s how I did it.&lt;/p&gt;
&lt;p&gt;I started by testing out the &lt;a href="https://www.pulumi.com/docs/iac/get-started/aws/"&gt;AWS getting started guide&lt;/a&gt; to get a feel for how Pulumi worked. This was a great move and I recommend everyone else to do the same.&lt;/p&gt;
&lt;p&gt;I was then ready to start importing my existing resources. The general workflow was to look at my existing Terraform code, rewrite it using Pulumi, and then import the existing resources. It was a bit time consuming in the beginning, but I got a lot faster at it after a few hours.&lt;/p&gt;
&lt;p&gt;Since Pulumi starts out &amp;ldquo;empty&amp;rdquo; you can rewrite and import a piece at a time. I&amp;rsquo;d recommend doing this because you will most probably do some mistakes initially, and it&amp;rsquo;s good to get early feedback.&lt;/p&gt;
&lt;p&gt;You can check the &lt;a href="https://www.pulumi.com/registry/packages/aws/api-docs/s3/bucket/"&gt;API reference&lt;/a&gt; for details on how to import each specific resource. The instructions on how to do it is usually at the bottom of the reference page for each resource type.&lt;/p&gt;
&lt;p&gt;Once I had everything migrated to Pulumi I set up a Gitlab CI/CD flow which allowed me to preview and apply the infrastructure changes. Up until then I&amp;rsquo;d been doing it locally from my own computer. If possible, I recommend doing it that way. The extra time taken by involving a separate CI/CD pipeline would make your migration take a lot longer. It&amp;rsquo;s perfectly fine when everything is done and dusted, however when learning Pulumi you&amp;rsquo;ll often need to use the &lt;code&gt;pulumi&lt;/code&gt; command to look at the resources.&lt;/p&gt;
&lt;h3 id="issues-workarounds-and-general-tips"&gt;Issues, workarounds and general tips&lt;/h3&gt;
&lt;h4 id="use-component-resources-to-group-resources"&gt;Use component resources to group resources&lt;/h4&gt;
&lt;p&gt;When your infrastructure starts growing it becomes hard to manage unless you group your resources. Pulumi&amp;rsquo;s solution to this are the so called &lt;a href="https://www.pulumi.com/docs/concepts/resources/#components"&gt;component resources&lt;/a&gt;. They are &amp;ldquo;logical components&amp;rdquo; which you define yourself.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pulumi stack
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;─ vt:RedisServer vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ aws:elasticache/parameterGroup:ParameterGroup vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ aws:ec2/securityGroup:SecurityGroup vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ aws:elasticache/cluster:Cluster vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see I&amp;rsquo;ve defined a component called &amp;ldquo;vt:RedisServer&amp;rdquo; which I use to group all the resources associated with my Redis server. You&amp;rsquo;ll get a graph representation of your whole infrastructure in the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/"&gt;Pulumi Web Console&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/graph.jpeg" alt="image.png"&gt;&lt;/p&gt;
&lt;p&gt;It might seem like a small thing, but it &lt;em&gt;really&lt;/em&gt; helps to have a logical grouping of your resources as your infrastructure grows. It also help because you can suddenly decide which resources your component exposes and which ones are &amp;ldquo;internal&amp;rdquo; to the component. Check out the code sample from earlier in the article to see how to do this using &lt;code&gt;self.&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id="importing-a-resource-that-has-a-parent-was-a-bit-confusing-at-first"&gt;Importing a resource that has a parent was a bit confusing at first&lt;/h4&gt;
&lt;p&gt;Each resource in pulumi has a globally unique &lt;a href="https://www.pulumi.com/docs/concepts/resources/#urns"&gt;URN&lt;/a&gt;. You can show the URNs for the infrastructure you&amp;rsquo;ve codeified in pulumi by issuing &lt;code&gt;pulumi stack --show-urns&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pulumi stack --show-urns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ vt:RedisServer vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ URN: urn:pulumi:prod::VT::vt:RedisServer::vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ aws:elasticache/parameterGroup:ParameterGroup vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ URN: urn:pulumi:prod::VT::vt:RedisServer&lt;span class="nv"&gt;$aws&lt;/span&gt;:elasticache/parameterGroup:ParameterGroup::vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ aws:ec2/securityGroup:SecurityGroup vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ URN: urn:pulumi:prod::VT::vt:RedisServer&lt;span class="nv"&gt;$aws&lt;/span&gt;:ec2/securityGroup:SecurityGroup::vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ aws:elasticache/cluster:Cluster vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ URN: urn:pulumi:prod::VT::vt:RedisServer&lt;span class="nv"&gt;$aws&lt;/span&gt;:elasticache/cluster:Cluster::vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s have a look at one of the URNs in more detail, shall we?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;urn:pulumi:prod::VT::vt:RedisServer&lt;span class="nv"&gt;$aws&lt;/span&gt;:elasticache/parameterGroup:ParameterGroup::vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;stack name: prod&lt;/li&gt;
&lt;li&gt;project name: VT&lt;/li&gt;
&lt;li&gt;parent resource type: vt:RedisServer&lt;/li&gt;
&lt;li&gt;resource type: aws:elasticache/parameterGroup:ParameterGroup&lt;/li&gt;
&lt;li&gt;resource name: vt-redis-prod&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All URNs need to be unique, which means every resource of the same type, with the same parent (in the same stack and project) needs to have a unique resource name.&lt;/p&gt;
&lt;p&gt;Normally I would have written and imported my parameter group definition something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# components/redis_server.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RedisServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ComponentResource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Redis server running on ElastiCache (single node).
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;vt:RedisServer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parameter_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;elasticache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParameterGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;family&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;redis6.x&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ResourceOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# __main__.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vt_prod_redis_server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RedisServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;vt-redis-prod&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And I would then try to import it like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# Executing the import (THIS WON&amp;#39;T WORK, DON&amp;#39;T TRY IT)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi import\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; aws:elasticache/parameterGroup:ParameterGroup\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; vt-redis-prod\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first &lt;code&gt;vt-redis-prod&lt;/code&gt; in the command above is the &lt;em&gt;identifier&lt;/em&gt; used by the &lt;code&gt;aws.elasticache.ParameterGroup&lt;/code&gt;. This is actually called &amp;ldquo;resource name&amp;rdquo; using Pulumi-speak. I prefer to call it identifier in my own code though, because &amp;ldquo;resource name&amp;rdquo; is too similar to the actual name it has to AWS for my liking.&lt;/p&gt;
&lt;p&gt;The second &lt;code&gt;vt-redis-prod&lt;/code&gt; is the actual name of my parameter group on AWS (remember we&amp;rsquo;re importing existing stuff).&lt;/p&gt;
&lt;p&gt;However, the above won&amp;rsquo;t work for one simple reason - the URN won&amp;rsquo;t match because we haven&amp;rsquo;t told Pulumi that this parameter group resource we&amp;rsquo;re importing is a child of our &lt;code&gt;RedisServer&lt;/code&gt; component. What&amp;rsquo;s the solution? Pretty simple, but somewhat obscure at the same time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# Executing the import (the right way)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi import\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --parent vt_prod_redis_server=urn:pulumi:prod::VT::vt:RedisServer::vt-redis-prod\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; aws:elasticache/parameterGroup:ParameterGroup\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; vt-redis-prod\
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You tell Pulumi about the parent by using the &lt;code&gt;--parent&lt;/code&gt; argument (this is the simple part). The &lt;em&gt;parent&lt;/em&gt; argument is a key=value pair, and the key is actually the &lt;em&gt;python variable name&lt;/em&gt; you&amp;rsquo;ve used in your code. If you scroll back up you can see that I stored my RedisServer instance in a variable called &lt;code&gt;vt_prod_redis_server&lt;/code&gt;. This part took longer than I&amp;rsquo;d like to admit for me to figure out.&lt;/p&gt;
&lt;p&gt;The value is the URN of the parent component, which you can get with &lt;code&gt;pulumi stack --show-urns&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id="you-cant-import-a-child-without-having-the-parent-in-place-first"&gt;You can&amp;rsquo;t import a child without having the parent in place first&lt;/h4&gt;
&lt;p&gt;That last one was a bit heavy, let&amp;rsquo;s take a breather and go for something a bit simpler!&lt;/p&gt;
&lt;p&gt;When importing a child component you need to import the parent first. If you simply run &lt;code&gt;pulumi up&lt;/code&gt; it will try to import all your resources all at once, and it won&amp;rsquo;t work because the parent haven&amp;rsquo;t been created yet.&lt;/p&gt;
&lt;p&gt;Instead simply do this first to update just a single resource:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pulumi up --target urn:pulumi:prod::VT::vt:RedisServer::vt-redis-prod
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will cause my &lt;em&gt;vt-redis-prod&lt;/em&gt; resource to be created in the Pulumi state. Nothing actually happens on AWS since it&amp;rsquo;s just a logical component. Once this is done you&amp;rsquo;ll be able to import all of it&amp;rsquo;s child resources as you saw above.&lt;/p&gt;
&lt;h2 id="writing-iam-json-policies-with-pulumi-outputs"&gt;Writing IAM (JSON) policies with Pulumi outputs&lt;/h2&gt;
&lt;p&gt;Imagine having an IAM policy that referenced an ECR repository, just as an example. You might want the policy to grant access only to that particular ECR repository. You might be temped to try something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;aws.iam.Policy(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;policy=json.dumps(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Version&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;2012-10-17&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Statement&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Sid&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;1&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Effect&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;Allow&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Action&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;ecr:GetAuthorizationToken&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Resource&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;ecr_repository.arn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;}))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;While this might look sensible, it won&amp;rsquo;t quite work. Remember early on I sad that Pulumi outputs are &lt;em&gt;futures&lt;/em&gt;, and not variables whose values you can access just like that. If you did like the example above your policy would just end up with something similar to &lt;code&gt;'Resource': &amp;lt;Pulumi.Output(...)&amp;gt;&lt;/code&gt; in it. Not quite what we wanted.&lt;/p&gt;
&lt;p&gt;Instead we have to tell Pulumi to resolve these futures, so we get the actual &lt;em&gt;value&lt;/em&gt; for them, like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;aws.iam.Policy(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;policy=ecr_repository.arn.apply(lambda&lt;/span&gt; &lt;span class="err"&gt;arn:&lt;/span&gt; &lt;span class="err"&gt;json.dumps(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Version&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;2012-10-17&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Statement&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Sid&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;1&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Effect&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;Allow&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Action&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;ecr:GetAuthorizationToken&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Resource&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;arn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;}))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you have more than one Output you need to access you can use &lt;code&gt;Output.all&lt;/code&gt;, like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;policy=(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;Output.all(origin_access_identity.iam_arn,&lt;/span&gt; &lt;span class="err"&gt;self.s&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;_bucket.arn)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;.apply(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;lambda&lt;/span&gt; &lt;span class="err"&gt;args:&lt;/span&gt; &lt;span class="err"&gt;json.dumps(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Version&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;2008-10-17&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Id&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;PolicyForCloudFrontPrivateContent&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Statement&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Sid&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;1&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Effect&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;Allow&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Principal&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;AWS&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;args[0]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Action&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;s&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;:GetObject&amp;#39;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;&amp;#39;Resource&amp;#39;:&lt;/span&gt; &lt;span class="err"&gt;f&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;args[1]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;/*&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;.apply&lt;/code&gt; method can also be useful for troubleshooting when you need to access the particular value of an output.&lt;/p&gt;
&lt;p&gt;This might seem tricky at first, but digest this for a bit, then have a look at the docs for &lt;a href="https://www.pulumi.com/docs/concepts/inputs-outputs/"&gt;Inputs and Outputs&lt;/a&gt; and I&amp;rsquo;m sure it&amp;rsquo;ll all make sense.&lt;/p&gt;
&lt;h3 id="dont-name-resources-unless-you-really-have-to"&gt;Don&amp;rsquo;t name resources unless you really have to&lt;/h3&gt;
&lt;p&gt;Pulumi is pretty smart when it comes to naming the actual resources on AWS. If you don&amp;rsquo;t specify a &lt;code&gt;name&lt;/code&gt; when creating a resource Pulumi will use the identifier and &lt;a href="https://www.pulumi.com/docs/support/faq/#why-do-resource-names-have-random-hex-character-suffixes"&gt;append a hex character suffix&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;This gives two great advantages. The first is that you can have multiple stacks next to each other, e.g. a &amp;ldquo;review&amp;rdquo; and a &amp;ldquo;production&amp;rdquo; environment. If you hard coded the names this wouldn&amp;rsquo;t be possible.&lt;/p&gt;
&lt;p&gt;The second advantage is that it makes replacement of resources much easier. If you hard code the name you leave Pulumi no choice but to tear down the existing resource before creating the replacement one. This makes a big difference if you are to perform a version update of one of your dependencies. In case you allow Pulumi to handle the naming it can create the new resource before terminating the previous one. This coupled with a DNS entry update can make for updates with virtually zero downtime.&lt;/p&gt;
&lt;p&gt;Since I imported existing resources I had to keep hard coded names in a few places. However I&amp;rsquo;ve taken the time to get rid of the hard coding as much as possible since then.&lt;/p&gt;
&lt;h3 id="integrating-with-cicd-gitlab"&gt;Integrating with CI/CD (Gitlab)&lt;/h3&gt;
&lt;p&gt;I use Gitlab for my Ci/CD, and I&amp;rsquo;m really happy with it. Let me show you what my very simple Pulumi pipeline looks like right now:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;stages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pulumi/pulumi-python:3.2.1 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Choose the right image for your language&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entrypoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# This is important for things to work&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pulumi stack select prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pulumi preview --color always --diff &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# I added &amp;#39;--diff&amp;#39; to always see more details&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;merge_requests &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Only run the preview on merge requests&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pulumi/pulumi-python:3.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;entrypoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pulumi stack select prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pulumi update --color always --diff --yes &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Answer &amp;#34;yes&amp;#34; when asking to apply the changes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;master &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Only run the update on the master branch (post merge)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see my pipeline is very simple for this little project which is still in an Alpha phase. There&amp;rsquo;s just the &amp;ldquo;production&amp;rdquo; environment, and changes are automatically applied once the MR is merged.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll have to make use of your gitlab-fu (or other-ci-cd-fu) to adapt this to your own needs. Read the &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/continuous-delivery/"&gt;docs from Pulumi&lt;/a&gt; to get started. It&amp;rsquo;s usually very simple and straight forward!&lt;/p&gt;
&lt;p&gt;I did things quite differently from what&amp;rsquo;s described in the Pulumi docs. I used the ready made image from Docker Hub, while they build their own. I did this to make the whole pipeline quicker. It seems to work really well so far, and I haven&amp;rsquo;t found any downsides to my approach (yet).&lt;/p&gt;
&lt;h3 id="i-couldnt-get-the-gitlab-integration-webhooks-to-work"&gt;I couldn&amp;rsquo;t get the Gitlab integration webhooks to work&lt;/h3&gt;
&lt;p&gt;You are normally able to have Pulumi post a report of the planned changes &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/continuous-delivery/gitlab-app/"&gt;attached to your merge request&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/migrating-my-infrastructure-from-terraform-to-pulumi/preview.jpeg" alt="image.png"&gt;&lt;/p&gt;
&lt;p&gt;However I couldn&amp;rsquo;t make this work because of authentication issues. With the help of their support (which was excellent btw) we figured out that it was related to the fact that I was using &lt;a href="https://docs.gitlab.com/ee/user/group/"&gt;Gitlab groups&lt;/a&gt; to organise my repositories.&lt;/p&gt;
&lt;p&gt;As things stand right now you have to create a Pulumi Organization for each Gitlab Group. There&amp;rsquo;s a bit of an issue with Pulumi&amp;rsquo;s pricing right now, because the only way to be able to get more than 1 organisation is to go for their enterprise plan.&lt;/p&gt;
&lt;p&gt;I think Pulumi will be fixing this in one way or another in the future. For now I&amp;rsquo;m still pretty happy just checking my changes from the Gitlab job output.&lt;/p&gt;
&lt;h3 id="whats-the-verdict"&gt;What&amp;rsquo;s the verdict?&lt;/h3&gt;
&lt;p&gt;So I&amp;rsquo;ve been using Pulumi for a few weeks now, and here are my impressions.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s really fast compared to Terraform. I didn&amp;rsquo;t even expect this one, but for some reason Pulumi manages to at least &amp;ldquo;feel&amp;rdquo; a lot faster. I haven&amp;rsquo;t done any measurements to verify this, but it definitely feels much faster.&lt;/p&gt;
&lt;p&gt;Their documentation is really good, although it took me a bit to learn to navigate it.&lt;/p&gt;
&lt;p&gt;Having type annotations is great! This makes it a lot more friendly to work with as a developer. No more passing around just plain strings in your code. However the type annotations doesn&amp;rsquo;t quite work in PyCharm because of how the Pulumi code is written. I consider this a PyCharm bug though, and I expect it to be fixed in the future. For now I can simply &lt;em&gt;ctrl+b&lt;/em&gt; the class in question, and read the type annotations from the source code.&lt;/p&gt;
&lt;p&gt;The Pulumi (Web) Console is a neat way to look at your infrastructure. I know there are similar solutions for Terraform, but I hadn&amp;rsquo;t used them personally.&lt;/p&gt;
&lt;p&gt;The developer ergonomics are great. Using your language of choice helps a lot. When running a company of one, like myself, it&amp;rsquo;s really important to limit the number of things you need to learn as much as possible. While HCL is simple it&amp;rsquo;s yet another language to remember. If you&amp;rsquo;re working at a larger company it&amp;rsquo;s a great way to encourage developers to do more infrastructure work.&lt;/p&gt;
&lt;p&gt;Pulumi is an open core type product, and you will have to pay to access the features on the higher tiers. Their current plans are very fairly priced. I myself is using the free community plan, which works great for me. There&amp;rsquo;s obviously the risk that they will remove the free plan in the future. However even if that happens I could either pay the fee, or transfer to state storage to AWS S3, and retain most of the product functionality. This feels like an acceptable level of risk for me.&lt;/p&gt;
&lt;p&gt;My goal was to do the whole migration in one day. In reality it ended up being closer to two days. However, given that I learned Pulumi and migrated ~130 resources in that amount of time I&amp;rsquo;d say that Pulumi is quite easy to get started with.&lt;/p&gt;
&lt;p&gt;All in all, I&amp;rsquo;m very happy with making the transition to Pulumi! I became way more productive managing my infrastructure. At the same time I ended up enjoying the work of doing so a lot more - which is really important too.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;This article was originally posted at &lt;a href="https://blog.ekik.org/my-experience-migrating-my-infrastructure-from-terraform-to-pulumi"&gt;https://blog.ekik.org/my-experience-migrating-my-infrastructure-from-terraform-to-pulumi&lt;/a&gt;. Reposted here with permission.&lt;/em&gt;&lt;/p&gt;</description><author>Erik Näslund</author><category>community</category><category>migration</category></item><item><title>2021 December Hackathon: Introduction</title><link>https://www.pulumi.com/blog/2021-dec-hackathon/</link><pubDate>Fri, 07 Jan 2022 09:39:28 -0600</pubDate><guid>https://www.pulumi.com/blog/2021-dec-hackathon/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/2021-dec-hackathon/index.png" /&gt;
&lt;p&gt;Pulumi&amp;rsquo;s &lt;a href="https://www.pulumi.com/blog/multi-lang-hackathon/"&gt;hackathon tradition&lt;/a&gt; continued in the last weeks of 2021 with our 2021 December hackathon. For one solid week, we had teams from across the company focus on improvements across the Pulumi ecosystem, and we brought in people from outside the engineering org to get perspectives on different needs. While there were some projects that were focused on internal work, there were still quite a few open-source projects that we can talk about publicly. We&amp;rsquo;ll get more details from some of those teams over a few more posts. In this post, however, we&amp;rsquo;re going to explore a bit about how we worked.&lt;/p&gt;
&lt;h2 id="setting-up-for-success"&gt;Setting up for success&lt;/h2&gt;
&lt;p&gt;We set up the teams for success before the hackathon began by starting discussions around project ideas in a Slack channel asynchronously. In in-person hackathons, teams often decide on projects the day of the start of the hackathon. By starting discussions early, we let folks decide on projects they&amp;rsquo;d be interested in contributing to and drove early architectural discussions so teams could hit the ground running. People also started to get excited about working on the various projects, and they were able to start connecting with folks outside of the engineering team to find time on their calendars early.&lt;/p&gt;
&lt;p&gt;Using a survey, we gathered what sorts of projects or areas of the ecosystem people were interested in working on, their timezone, and how they would like to collaborate. By using this data to sort people into teams, we ensured that people who were interested in learning about new areas of the ecosystem could find the right projects, that people who needed to work in a more synchronous environment could be paired with others in their timezone, and that people who worked similarly could find people who worked like them. It was an interesting experiment.&lt;/p&gt;
&lt;h2 id="working-remotely"&gt;Working remotely&lt;/h2&gt;
&lt;p&gt;One cool thing that we tracked this round is all of the different ways we collaborated across the different projects. In general, Pulumi is a remote workplace, and none of the teams were co-located for this hackathon. As a result, we had to consider how teams might work across timezones and outside of the classic physical co-located team dynamic. Each team got to pick the best ways for them to collaborate. Our teams&amp;rsquo; preferences ranged from daily standups over Zoom to collaboration solely on Slack to extensive pair programming and Zoom hangouts. In all, each team used multiple ways to communicate and engage depending on which parts of their projects they were working on. Teams working on explorations of possible solutions often found that pair programming remotely was a great way to brainstorm, for example. Once teams had a solid sense of what needed to be done to get to the next part of a project, many still attended a hackathon-wide Zoom hangout session daily to have someone to hang out with and discuss any issues that arose. The whole org also had the opportunity to get to know one another a little better, and it did not have the feeling of lost time or forced socialization that weekly virtual watercoolers can have after a couple of meetings as many have found during this period of forced virtual interactions.&lt;/p&gt;
&lt;h2 id="showing-off-what-we-did"&gt;Showing off what we did&lt;/h2&gt;
&lt;p&gt;During the demo at the end of the hackathon, we asked teams to self-report which strategies they found the most helpful, what they learned, and obviously what the results of their hackathon project were. We found that everyone level-set to how their team chose to work, and the pairing of people based on location and work preferences helped a lot to have teams succeed.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;We&amp;rsquo;ll have more from each team soon! Keep watch on this space for new posts about hackathon projects.&lt;/p&gt;
&lt;p&gt;If you like our way of working and are interested in a new position, we have a lot of positions open right now and will have more in the future! Please head over to our &lt;a href="https://www.pulumi.com/careers/"&gt;careers page&lt;/a&gt; to find out how to apply.&lt;/p&gt;</description><author>Laura Santamaria</author><category>hackathon</category><category>pulumi-culture</category></item><item><title>Kubecon NA 2021 Roundup</title><link>https://www.pulumi.com/blog/kubecon-na-2021-roundup/</link><pubDate>Mon, 08 Nov 2021 22:50:38 +0000</pubDate><guid>https://www.pulumi.com/blog/kubecon-na-2021-roundup/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/kubecon-na-2021-roundup/index.png" /&gt;
&lt;p&gt;KubeCon North America 2021 is over, but the recordings are now online! Every talk you wanted to attend and couldn’t is available on YouTube, so here’s some highlights—cloud native trends, updates from projects and SIGs, and a few of my favorite talks!&lt;/p&gt;
&lt;h4 id="sbom-is-coming-why-you-should-care-and-how-you-can-help---frederick-kautz--allan-friedman"&gt;SBOM is Coming: Why You Should Care and How You Can Help - Frederick Kautz &amp;amp; Allan Friedman&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/4wUejdZ6KHM?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;A major trend throughout the conference was supply chain security and software bill of materials (SBOMs). There were quite a few talks on these subjects, but Frederick Kautz and Allan Friedman give a great overview of exactly what an SBOM is, and why it’s important.&lt;/p&gt;
&lt;h4 id="notary-state-of-the-container-supply-chain---justin-cormack-docker--steve-lasker-microsoft"&gt;Notary: State of the Container Supply Chain - Justin Cormack, Docker &amp;amp; Steve Lasker, Microsoft&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/hpcQJ21mn_g?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;On supply chain security, Steve Lasker presents updates to Notary v2. It’s changed quite a bit since v1 and there are more changes on the horizon. With the rising concerns surrounding supply chain security, I expect Notary and tools like it to be increasingly important. No worries if you aren’t already familiar with Notary—Steve explains it well.&lt;/p&gt;
&lt;h4 id="a-vulnerable-tale-about-burnout---julia-simon-cloudops"&gt;A Vulnerable Tale About Burnout - Julia Simon, CloudOps&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/lpiXbfOTNYw?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Taking things to a more human place, burnout was a common theme this year. It’s something that we don’t talk about as much as we should, but close to two years of isolation is forcing us all to confront it in ways we may not have expected. This talk by Julia Simon is important to watch not just so that you can learn to recognize these problems in yourself, but so that you can recognize them in your peers.&lt;/p&gt;
&lt;h4 id="podsecuritypolicy-replacement-past-present-and-future---tabitha-sable--tim-allclair"&gt;PodSecurityPolicy Replacement: Past, Present, and Future - Tabitha Sable &amp;amp; Tim Allclair&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/HsRRmlTJpls?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;PodSecurityPolicy (PSP) has been deprecated. Many of you may be relying on this, and deprecations frequently sound scary, but Tabitha Sable and Tim Allclair are here to soothe your fears. They go to great lengths explaining what PSP is, why it was deprecated, what exactly this means for people relying on it, and where we’re going next.&lt;/p&gt;
&lt;h4 id="sig-contributor-experience-deep-dive---alison-dowdney-weaveworks--christoph-blecker-red-hat"&gt;SIG Contributor Experience Deep Dive - Alison Dowdney, Weaveworks &amp;amp; Christoph Blecker, Red Hat&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/QOiyWWFjG5Q?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;An open source project lives or dies by its contributors, both technical and non-technical. Kubernetes is huge and requires a lot of contributors to keep it growing, so we have SIG Contributor Experience to make sure they stay happy and the community stays healthy. Alison Dowdney and Christoph Blecker go into just how SIG Contributor Experience operates, plus updates. If you’re in a leadership position for an open source project, there are some lessons to be learned from this talk.&lt;/p&gt;
&lt;h4 id="kubernetes-exposed-seven-of-nine-hidden-secrets-that-will-give-you-ian-coldwater--brad-geesaman"&gt;Kubernetes Exposed! Seven of Nine Hidden Secrets That Will Give You&amp;hellip; Ian Coldwater &amp;amp; Brad Geesaman&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/JBbVTmrZ45E?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;No Kubecon is complete without Ian Coldwater, this time joined by Brad Geesaman (and, briefly, a second Ian Coldwater) to go into some not-so-obvious but oh-so-important pitfalls and hidden security concerns within Kubernetes. Even if you caught this talk live, it’s worth watching again to make sure you’re secured against these issues, or you might find a goose haunting your cluster.&lt;/p&gt;
&lt;h4 id="beyond-kubernetes-security---ellen-körbes-tilt--tabitha-sable-datadog"&gt;Beyond Kubernetes Security - Ellen Körbes, Tilt &amp;amp; Tabitha Sable, Datadog&lt;/h4&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/-4W3ChRVeLI?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Finally, it would be remiss of me to not mention Ellen and Tabitha’s cinematic contribution to this year’s Kubecon North America. Beyond Kubernetes Security is the spiritual successor to their talk from the last Kubecon Europe, once again going into how some security concepts and exploits work in Kubernetes, but presented as a short film involving crime, time travel, breakups, and Ellen’s collection of old electronics.&lt;/p&gt;
&lt;p&gt;The quality of the content was incredible across the board this year, whether the speakers were live or presenting virtually, forcing some difficult decisions around selecting my schedule for talks to attend and how many I could feasibly put in this blog before it got way too long. Fortunately, all of them are on the &lt;a href="https://www.youtube.com/c/cloudnativefdn/videos"&gt;CNCF YouTube channel&lt;/a&gt; now, including talks from the various co-located events. Dig through!&lt;/p&gt;
&lt;p&gt;Kubecon North America was simultaneously a strange and familiar event. It’s been nearly two years since most of us have been at a conference, and while that certainly made things awkward at times while we all readjusted to seeing other humans in the flesh, our slow return to something vaguely familiar seems to have been a success. I sincerely hope to see you all in person at the next Kubecon EU in Valencia.&lt;/p&gt;
&lt;p&gt;Honk &amp;lt;3,&lt;/p&gt;
&lt;p&gt;Kat&lt;/p&gt;</description><author>Kat Cosgrove</author><category>kubecon</category><category>kubernetes</category><category>conferences</category></item><item><title>The Industry Comes Together for the Cloud Engineering Summit</title><link>https://www.pulumi.com/blog/the-industry-comes-together-for-the-cloud-engineering-summit-2021/</link><pubDate>Wed, 06 Oct 2021 06:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/the-industry-comes-together-for-the-cloud-engineering-summit-2021/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/the-industry-comes-together-for-the-cloud-engineering-summit-2021/index.png" /&gt;
&lt;p&gt;When we launched the &lt;a href="https://www.youtube.com/playlist?list=PLyy8Vx2ZoWlpE6LxGPnfLfBQLbC7zX8FT"&gt;first-ever Cloud Engineering Summit&lt;/a&gt; last year, we were humbled by the generosity and support from partners and sponsors across the industry who helped to make the summit a success. For this year&amp;rsquo;s event, we’re equally thrilled to have an amazing group of sponsors participating in the summit and it’s worth a quick ‘guided tour’ of the teams that are helping us to pull off this amazing event.&lt;/p&gt;
&lt;h2 id="amazon-web-services"&gt;Amazon Web Services&lt;/h2&gt;
&lt;p&gt;AWS was an inaugural sponsor for the Cloud Engineering Summit with a talk from Alex Head about cost optimization. The AWS team returns again this year with four sessions: Emily Freeman will talk about &lt;em&gt;Rethinking the SDLC&lt;/em&gt;, Rahul Sharma will share his team’s experience building the brand new &lt;a href="https://aws.amazon.com/blogs/aws/announcing-aws-cloud-control-api"&gt;Cloud Control API&lt;/a&gt; in &lt;em&gt;How AWS architects APIs for hyper-scale&lt;/em&gt;, and Jenna Pederson will show you how to &lt;em&gt;Bring software development practices to your infrastructure&lt;/em&gt;. Finally, Ken Exner will be chatting with Joe Duffy about the future of tooling for modern cloud infrastructure.&lt;/p&gt;
&lt;p&gt;We’ll cap off the summit in a free, post-event workshop with Marina Novikova and Laura Santamaria showing you how to get started on AWS.&lt;/p&gt;
&lt;h2 id="apple"&gt;Apple&lt;/h2&gt;
&lt;p&gt;New to the Cloud Engineering Summit this year, cloud services experts Fariba Khan and Stephen Van Gordon will share their experiences managing infrastructure at scale in Lifecycle of a Pulumi Program. They’ll talk about building a custom state backend, using CI/CD tooling, and the Pulumi Automation API to empower teams to provision secure-by-default configurations automatically.&lt;/p&gt;
&lt;h2 id="google-cloud"&gt;Google Cloud&lt;/h2&gt;
&lt;p&gt;Last year we hosted a fantastic talk from Jason (Jay) Smith who showed attendees how to stand up a serverless platform. This year, we’re proud to include Google Cloud as a sponsor and feature a keynote from Kelsey Hightower with Joe Duffy.&lt;/p&gt;
&lt;p&gt;After the summit, you can also join Kat Cosgrove for free hands-on training showing you how to get started with Google Cloud.&lt;/p&gt;
&lt;h2 id="microsoft"&gt;Microsoft&lt;/h2&gt;
&lt;p&gt;The 2020 Cloud Engineering Summit featured Amanda Silver in a Future of Cloud Engineering panel and Adora Nwodo showed everyone how to manage apps and infrastructure in a single CI/CD pipeline. Adora will return to the summit again this year to talk about &lt;em&gt;Software engineering in infrastructure engineering&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;For those looking to expand their cloud engineering skillset after the summit, Matt Stratton will host a workshop to show attendees how to get started with Azure.&lt;/p&gt;
&lt;h2 id="nginx"&gt;NGINX&lt;/h2&gt;
&lt;p&gt;We’ve spent a lot of time with the NGINX team over the past year in their quest to make it easier than ever to get to production with Kubernetes. Join first-time summit speakers Damian Curry and Elijah Zupancic for a lightning talk followed by NGINX office hours to learn about &lt;em&gt;Building a modern app reference architecture for Kubernetes&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Then, if you’re ready for some hands-on Kubernetes help, join our post-event workshop &lt;a href="https://www.pulumi.com/events/from-zero-to-production-in-kubernetes/"&gt;From Zero to Production in Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="bridgecrew"&gt;Bridgecrew&lt;/h2&gt;
&lt;p&gt;New to the summit this year, Bridgecrew’s Steve Giguere is joining the Build track to share &lt;em&gt;Taking a Kubernetes Deployment from Default to Secure&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="circleci"&gt;CircleCI&lt;/h2&gt;
&lt;p&gt;Long-time collaborator Angel Rivera from &lt;a href="https://circleci.com/"&gt;CircleCI&lt;/a&gt; joins the Deploy track to talk about &lt;em&gt;Building Arm Compatible CI/CD Pipelines&lt;/em&gt; and show you how to take advantage of Arm architectures in both your pipelines and workloads.&lt;/p&gt;
&lt;h2 id="github"&gt;GitHub&lt;/h2&gt;
&lt;p&gt;The GitHub team participated in three sessions last year including the Architectures and Platforms and Security and Policy panels. This year, the team returns with Rizel Bobb-Semple delivering a plenary session showing you how to get &lt;em&gt;From Code to Cloud&lt;/em&gt; without learning new tools.&lt;/p&gt;
&lt;h2 id="honeycomb"&gt;Honeycomb&lt;/h2&gt;
&lt;p&gt;If you missed Charity Major’s summit session last year about Testing In Production, stop reading and go watch it. Then, register for Liz Fong-Jones’s Build track session this year: &lt;em&gt;What is OpenTelemetry&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="ns1"&gt;NS1&lt;/h2&gt;
&lt;p&gt;Last year, Johnathan Sullivan joined the Culture, Process, and Tools panel, and we’re excited to welcome Chris Buijs to this year’s Deploy panel.&lt;/p&gt;
&lt;h2 id="and-many-more"&gt;&amp;hellip;and many more&lt;/h2&gt;
&lt;p&gt;Beyond the teams and sessions mentioned above, the Cloud Engineering Summit wouldn’t be possible without help and support from a long list of sponsors and collaborators including Codefresh, Split, and Uffizzi. Watch the replay to see what all the fuss is about.&lt;/p&gt;</description><author>Isaac Harris</author><category>cloud-engineering-summit</category></item><item><title>Cloud Engineering Summit Build Track</title><link>https://www.pulumi.com/blog/cloud-engineering-summit-build-track/</link><pubDate>Thu, 16 Sep 2021 13:47:25 -0500</pubDate><guid>https://www.pulumi.com/blog/cloud-engineering-summit-build-track/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/cloud-engineering-summit-build-track/index.png" /&gt;
&lt;p&gt;The Cloud Engineering Summit 2021 is coming up fast, and the speakers are out! To get you ready to attend, let’s take a look at the sessions for the Build track.&lt;/p&gt;
&lt;p&gt;The Cloud Engineering Summit’s three tracks are built around three concepts: Build, Manage, and Deploy. I’m Kat Cosgrove, and I was responsible for selecting your speakers for the Build track! For us, that means building cloud applications and infrastructure with Modern Infrastructure as Code using general purpose programming languages. We embrace the fact that modern cloud applications have blurred the lines between the application and the infrastructure, and that success requires at least some level of proficiency in both. Whether you’re full stack or lean more towards one area, all cloud engineers apply a software engineering mindset and practices to building and testing applications and the underlying cloud infrastructure. This includes using standard programming languages, applying software principles such as reusability and abstractions and testing, and leveraging the rich ecosystem of software development tools.&lt;/p&gt;
&lt;p&gt;Without further ado, let’s take a look at each of the talks I’ve selected for you!&lt;/p&gt;
&lt;p&gt;Starting us off is the inimitable Kris Nóva with &lt;em&gt;Infrastructure as Software.&lt;/em&gt; She’s going to be talking about why Turing complete config management is an antipattern, and why we should be putting the Dev back in DevOps. Nóva is an incredible speaker and engineer. Any talk she gives promises to be hot fire, so I wouldn&amp;rsquo;t miss this one.&lt;/p&gt;
&lt;p&gt;Don’t like repeating yourself? Yeah, me neither. Fortunately, we have Sam Cogan to present his talk, &lt;em&gt;Reuse, Don&amp;rsquo;t Repeat - Creating an Infrastructure as Code Module Library&lt;/em&gt;. Personally, I’m a huge fan of reusable modules for any purpose, when they’re built in such a way that it reduces overall toil and makes your codebase easier to understand. This talk should be useful for everyone.&lt;/p&gt;
&lt;p&gt;Helping us ask and answer the right questions to make organizational and technological decisions is Joep Piscaer, presenting &lt;em&gt;Kubernetes isn’t the answer, but what was the question again?&lt;/em&gt; I love Kubernetes, but it can be complex, and sometimes that complexity means it’s not the right solution for you (yet.) If you struggle with finding the right questions to ask about your tech needs, this talk could help.&lt;/p&gt;
&lt;p&gt;I’m kind of nosy. I like knowing as much as possible about what’s going on inside of my applications and infrastructure. It’s hard to present all of that data in a way that’s easy to consume rather than overwhelming, though. Fortunately, we have Liz Fong-Jones to help out with her talk, &lt;em&gt;What is OpenTelemetry?&lt;/em&gt; Don’t miss this one if you’re curious about a better way to gain insights into your distributed systems.&lt;/p&gt;
&lt;p&gt;You’d think that when a particular tool is widely accepted as the industry standard for accomplishing a task, there’d be a wealth of information out there on how to accomplish most important tasks in an accessible, actionable way. Unfortunately, that’s not really the case. Fortunately, we have Steve Giguere presenting &lt;em&gt;Hands-on: Taking a K8s Deployment from Default to Secure,&lt;/em&gt; wherein he’ll take us through securing an NGINX deployment!&lt;/p&gt;
&lt;p&gt;Curious about how a big product gets built? Rahul Sharma is with us to talk about &lt;em&gt;How AWS architects APIs for hyper scale.&lt;/em&gt; He won’t just be talking technology; we’ll also hear about the cultural changes required internally to launch a product, and how engagement with customers and partners helps shape the course of development.&lt;/p&gt;
&lt;p&gt;Last but certainly not least is Heidi Waterhouse presenting &lt;em&gt;The Future Should Be Uneven&lt;/em&gt;, a talk about personalization and accessibility in web design. Accessible design benefits us all, whether we actually &lt;em&gt;need&lt;/em&gt; the accommodation or not. The sooner we all understand and embrace that, the better, so Heidi will walk us through some common accessibility settings that are really just good design for everyone.&lt;/p&gt;
&lt;p&gt;Explore all of the rest of the great sessions, and don&amp;rsquo;t forget to register for the cloud engineering summit!&lt;/p&gt;</description><author>Kat Cosgrove</author><category>pulumi-events</category><category>cloud-engineering</category><category>infrastructure-as-code</category></item><item><title>Preview of the Deploy Track at Cloud Engineering Summit 2021</title><link>https://www.pulumi.com/blog/cloud-engineering-summit-deploy-track/</link><pubDate>Wed, 15 Sep 2021 09:00:00 -0500</pubDate><guid>https://www.pulumi.com/blog/cloud-engineering-summit-deploy-track/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/cloud-engineering-summit-deploy-track/index.png" /&gt;
&lt;p&gt;Cloud Engineering Summit 2021 is almost here! We’ve got a great line up this year.&lt;/p&gt;
&lt;p&gt;Our tracks are built around the three pillars of cloud engineering: Build, Deploy, and Manage. I’m your track chair for the Deploy track, the track focused on automating and managing infrastructure. Deploy is all about unifying systems so everything in a cloud-based system is shipped together from the same automated, auditable process, reducing human error and improving quality across the board. That could mean focusing on automated testing and linting of infrastructure as code, providing shared services platforms for others to use in their pipelines, or exploring how unified and automated infrastructure changes engineering culture in an organization.&lt;/p&gt;
&lt;p&gt;In no particular order, let’s go explore the Deploy track lineup.&lt;/p&gt;
&lt;p&gt;Trying to get a handle on way too many environments across your pipelines? Adora Nwodo, Software Engineer at Microsoft, will explore bringing standard software engineering practices to solve the problem of maintaining many environments and configurations in a repeatable fashion. Adora has a very accessible way of explaining complex concepts in her blog and videos (find her at AdoraHacks), and I’m really looking forward to getting her perspective.&lt;/p&gt;
&lt;p&gt;How can we improve the security of these unified processes? Alyssa Miller, Business Information Security Officer (BISO) at S&amp;amp;P Global Ratings, will discuss how threat modeling can improve CI/CD pipelines and general security. I’m excited to have Alyssa join us to help us understand how security should be part of the Deploy pillar; her Pitmaster’s Guide to Security is really good and I recommend watching it!&lt;/p&gt;
&lt;p&gt;When you’re trying to share what you’re doing, you could share your code, but how do you share your infrastructure? Peter McKee, Head of Developer Relations and Advocacy at Docker, will demonstrate how to build into pipelines the ability to share features and changes in applications with others as a continuous preview. Peter’s a fantastic teacher who always has a great hands-on presentation in his back pocket, so I’m really looking forward to finding out what he has in store for us.&lt;/p&gt;
&lt;p&gt;Data builds up while you’re building out, deploying, and managing cloud-based systems. How can you manage data while deploying your cloud infrastructure? Andy Dang, Co-Founder and Engineering Lead at WhyLabs, will talk about data integrity, observability, and monitoring with an open-source project called whylogs. Always love having a preview of an open-source project in the program, and I think data’s going to continue to be a big question for cloud engineering, so Andy’s talk was very welcome!&lt;/p&gt;
&lt;p&gt;What about ARM-based systems? Apple certainly got into the game with their M1 chip, so it’s a platform you have to consider when doing deployments. Angel Rivera, Senior Developer Advocate at CircleCI, will explore how to make pipelines and workloads ARM compatible and capable of supporting ARM on various products. ARM-based systems are some of my favorites (yay Arduino and Raspberry Pi!), and they’re also really important considerations if you’re in the mobile or embedded space, so I can’t wait to hear Angel’s take.&lt;/p&gt;
&lt;p&gt;How about some focus on doing all of this at scale? Jenna Pederson, Developer Advocate at AWS, will explore how bringing all of the best practices from software development to pipelines will help make working with cloud-based resources consistent and secure. I’m so happy Jenna could join us! Her content is wonderfully accessible and really explains technical concepts and complex systems clearly for all levels (which is my jam!). You don’t want to miss her talk!&lt;/p&gt;
&lt;p&gt;Finally, how does all of this stuff work in a real life team? Evan Bradley, Software Engineer, and Tom Carrio, Senior Software Engineer, from Dynatrace are going to take us through bringing it all together with a real-life team, discussing the experiences they’ve had over time as they’ve implemented everything. I’m really excited to have folks bring their stories of what it’s all like so we can share pitfalls and solutions to move forward together. I think you’ll enjoy Evan and Tom’s talk, too!&lt;/p&gt;
&lt;p&gt;Explore all the sessions, and don&amp;rsquo;t forget to register for Cloud Engineering Summit. I can&amp;rsquo;t wait to chat with you virtually at Cloud Engineering Summit 2021!&lt;/p&gt;</description><author>Laura Santamaria</author><category>cloud-engineering</category><category>continuous-delivery</category><category>pulumi-events</category></item><item><title>Preview of the Manage Track at Cloud Engineering Summit 2021</title><link>https://www.pulumi.com/blog/cloud-engineering-summit-manage-track/</link><pubDate>Mon, 13 Sep 2021 08:00:00 -0500</pubDate><guid>https://www.pulumi.com/blog/cloud-engineering-summit-manage-track/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/cloud-engineering-summit-manage-track/index.png" /&gt;
&lt;p&gt;The Cloud Engineering Summit 2021 is coming up fast, and the speakers are out! To get you ready to attend, let’s take a look at the sessions for the Manage track.&lt;/p&gt;
&lt;p&gt;The Cloud Engineering Summit’s three tracks are built around three concepts: Build, Manage, and Deploy. I’m Matt Stratton, and I’m your charismatic track chair for Manage. For us, that means managing cloud applications and infrastructure with Policy as Code, visibility, and access controls. For example, managing infrastructure with policies that detect configuration drift, enforce best practices, and even prevent compliance violations before deployment. It means building visibility across your cloud infrastructure so that you always understand its current and past states, including detailed audit history. Finally, you ensure the right guardrails and controls are set in place so that distributed teams can securely develop.&lt;/p&gt;
&lt;p&gt;Without further ado, let’s take a look at each of the talks I’ve selected for you!&lt;/p&gt;
&lt;p&gt;Overwhelmed by permissions and authorization? Me, too. Fortunately, we have Joy Ebertz presenting &lt;em&gt;Authorization: Ensuring Only Ada Can Access Her Files&lt;/em&gt;. Joy is going to cover the various authorization models available to us, with use-cases for each. Authorization can be overwhelming if you don&amp;rsquo;t have a good grasp of the options available to your organization and an understanding of what works when, so I’m excited for this one.&lt;/p&gt;
&lt;p&gt;Taking a higher-level view, Quintessence Anx will be presenting &lt;em&gt;DevSecOps and Secure Incident Response&lt;/em&gt;. The introduction of security to the DevOps equation means some shifts in the way we think about the software development lifecycle, and Quintessence is uniquely qualified to talk about why that’s true. A look inside PagerDuty’s 14 Step Secure Incident Response process promises to be interesting for anyone involved in either development or operations.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think we have the ability to predict the future, but J. Paul Reed wonders if we can develop the ability to forecast incidents just as we have learned to have staggeringly accurate weather short-term forecasts. With &lt;em&gt;Forecasting the Future: Creating a Radar for Risk&lt;/em&gt;, Paul will share with us how Netflix uses Risk Radar to collect and make sense of risk in their sociotechnical systems.&lt;/p&gt;
&lt;p&gt;When we talk about infrastructure as code, there&amp;rsquo;s more to it than just the code! Fariba Khan and Stephen Van Gordon will take us on a journey with &lt;em&gt;Lifecycle of a Pulumi Program&lt;/em&gt; to share how they leverage a custom state backend with SSO, RBAC, and programmatically configurable pipelines powered by CI/CD tooling and the Pulumi Automation API to drive IaC at their organization.&lt;/p&gt;
&lt;p&gt;Snowflake’s Charles Xu will be here to talk about &lt;em&gt;Day-two Operation of Multi-cloud Kubernetes and Vault&lt;/em&gt;, a very cool overview of Snowflake’s Kubernetes infrastructure and how Pulumi helps, from blue-green updates, to managing Hashicorp Vault, to rotating TLS certificates. This is a pretty complex topic, so I’m very interested to see where it goes!&lt;/p&gt;
&lt;p&gt;Gremlin&amp;rsquo;s Jason Yee comes to us with &lt;em&gt;Trailblazers: exploration, discovery, &amp;amp; navigating failure&lt;/em&gt; - a set of topics that I personally find fascinating and essential! I think we are constantly in a state of discovery and understanding of our complex systems, and learning how to explore them - and work through the inevitable failures - helps us build and operate even more reliable systems.&lt;/p&gt;
&lt;p&gt;Rounding things out is the always incredible Tim Banks, with &lt;em&gt;Toxic Velocity: Speed Kills&lt;/em&gt;. In this talk, Tim is going to cover the various stressors that put pressure on both organizations and individuals, how they affect us, and what it looks like when things start to spiral out of control. I’m excited for this one because while crashes do happen, we’d all like them to happen less often (or not at all!), and being able to identify some of these things before they become a real problem is better for our businesses and our people.&lt;/p&gt;
&lt;p&gt;Explore all of the rest of the great sessions, and don&amp;rsquo;t forget to register for the cloud engineering summit!&lt;/p&gt;</description><author>Matty Stratton</author><category>cloud-engineering</category><category>security</category><category>pulumi-events</category></item><item><title>Demos from the Multi-Language Component Hackathon</title><link>https://www.pulumi.com/blog/multi-lang-hackathon/</link><pubDate>Thu, 24 Jun 2021 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/multi-lang-hackathon/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/multi-lang-hackathon/index.png" /&gt;
&lt;p&gt;At Pulumi, we have a tradition of hosting hackathons every so often to play with concepts and ideas that we may not typically encounter in our day-to-day product building activities. This past week, we’ve had two separate back-to-back hackathons. Our first hackathon, which was open to the community, focused on using our new &lt;a href="https://www.pulumi.com/blog/pulumiup-pulumi-packages-multi-language-components/"&gt;multi-language component capabilities&lt;/a&gt;. Multi-language components allow developers to author reusable infrastructure abstractions in one language and make them available to others in all the languages that Pulumi supports. We were really excited to see what everyone would build!&lt;/p&gt;
&lt;p&gt;We had a kickoff meeting on Tuesday morning where Lee Briggs walked participants through the &lt;a href="https://www.youtube.com/watch?v=_RXvNS5N8A8"&gt;basic steps for bringing up a multi-language component&lt;/a&gt;. If you’re interested in seeing the kickoff meeting, we’ve recorded it and have made it available for viewing on &lt;a href="https://youtu.be/Ogg5cs6vPfc"&gt;Pulumi TV&lt;/a&gt;. After the walk-through, teams got down to business!&lt;/p&gt;
&lt;p&gt;We had some great ideas, including but not limited to components for a simplified Google Cloud project setup, an Azure web app service container, and an Amazon SageMaker model with a frontend for serving it.&lt;/p&gt;
&lt;p&gt;As part of the hackathon, we received some great feedback from all the participants on improving the multi-language authoring experience, including reducing boilerplate code, ways to improve on the schema authoring experience, and documentation suggestions. We’re keen to continue to refine the experience.&lt;/p&gt;
&lt;p&gt;Thank you to all the participants! If you’d like to see some of the components in action, you can &lt;a href="https://youtu.be/U7-eYSpB4o8"&gt;watch our demo session&lt;/a&gt;. We saw the following component demos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Run my d#!n container” which demonstrated a component to run a container on any of the major cloud providers.&lt;/li&gt;
&lt;li&gt;A component that brings up a new Google Cloud Project.&lt;/li&gt;
&lt;li&gt;A component for creating an AWS Lambda function fronted by API Gateway&lt;/li&gt;
&lt;li&gt;A component for creating an Amazon CloudFront distribution backed by an S3 bucket&lt;/li&gt;
&lt;li&gt;A component that runs an AWS Lambda function as a cron.&lt;/li&gt;
&lt;li&gt;API Gateway component that simplifies creating Amazon API Gateway resources&lt;/li&gt;
&lt;li&gt;A serverless component that consumes Serverless configuration&lt;/li&gt;
&lt;li&gt;Replicated S3 Bucket component to simplify cross-region object replication&lt;/li&gt;
&lt;li&gt;Miniflux component that deploys the Miniflux service&lt;/li&gt;
&lt;li&gt;.NET Boilerplate for multi-language components&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stay tuned for our next post on our general hackathon results. In our general hackathon, the Pulumi team tried out new ideas and investigated ways to improve upon the Pulumi experience!&lt;/p&gt;
&lt;p&gt;You can watch the hackathon including the intro multi-lang components, the hackathon kickoff, and the demo session.&lt;/p&gt;
&lt;h3 id="introduction-to-building-multi-lang-components"&gt;Introduction to Building Multi-lang Components&lt;/h3&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/_RXvNS5N8A8?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="multi-lang-hackathon-kick-off"&gt;Multi-lang Hackathon Kick-Off&lt;/h3&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Ogg5cs6vPfc?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="hackathon-demos"&gt;Hackathon Demos!&lt;/h3&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/U7-eYSpB4o8?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;</description><author>Lee Zen</author><category>multi-language-component</category><category>hackathon</category></item><item><title>Hitesh's Intern Experience at Pulumi</title><link>https://www.pulumi.com/blog/hiteshs-experience-as-a-pulumi-intern/</link><pubDate>Fri, 11 Jun 2021 09:53:45 -0700</pubDate><guid>https://www.pulumi.com/blog/hiteshs-experience-as-a-pulumi-intern/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/hiteshs-experience-as-a-pulumi-intern/index.png" /&gt;
&lt;p&gt;Hi everyone, I’m &lt;a href="https://www.linkedin.com/in/hitesh-boinpally"&gt;Hitesh Boinpally&lt;/a&gt;, a junior studying Computer Science at the University of Washington. I was offered the opportunity to intern for Pulumi over the past three months, and here’s how it looked!&lt;/p&gt;
&lt;h2 id="technical-work"&gt;Technical Work&lt;/h2&gt;
&lt;p&gt;My overall project was to build a test harness for Pulumi&amp;rsquo;s converter tools such as &lt;a href="https://github.com/pulumi/arm2pulumi"&gt;&lt;code&gt;arm2pulumi&lt;/code&gt;&lt;/a&gt; and tf2pulumi. The project involved several pieces, all of which meant learning about technologies I hadn&amp;rsquo;t encountered before.&lt;/p&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.74fadd1b94bae866bccf29a780f184a71c5cfc34c8677be70da8fe2ab0309b9e.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;As of Pulumi CLI v3.71.0, &lt;code&gt;tf2pulumi&lt;/code&gt; has been replaced with &lt;code&gt;pulumi convert --from terraform&lt;/code&gt;. &lt;a href="https://www.pulumi.com/blog/converting-full-terraform-programs-to-pulumi/"&gt;Converting Full Terraform Programs to Pulumi blog&lt;/a&gt; has more details.&lt;/div&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;A program that ran the test itself and generated results in a program readable way, which I wrote in Go.&lt;/li&gt;
&lt;li&gt;Running that program to generate historical data over time through GitHub Actions consistently.&lt;/li&gt;
&lt;li&gt;The cloud infrastructure part, which was uploading the test results into an AWS Redshift table for human-accessible analysis. Here was where I got to utilize Pulumi and better understand infrastructure as code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of these were fascinating to learn about and stretched my knowledge in directions I hadn’t previously explored.&lt;/p&gt;
&lt;p&gt;I began with setting up the harness for &lt;a href="https://github.com/pulumi/arm2pulumi"&gt;&lt;code&gt;arm2pulumi&lt;/code&gt;&lt;/a&gt;. The Go program had already been written, so I needed to focus on the GitHub Actions for CI and cloud infrastructure aspects. I set up the CI quickly, but the cloud infrastructure took some time. Wrangling with AWS’s different IAM roles, cross-account permissions, and how to utilize the different tools was complex and challenging. However, I learned a lot about these different spaces and gained valuable experience. Further, I appreciated the advantages of Pulumi, as I could quickly undo/redo changes incrementally, rather than making manual changes in the AWS Console.&lt;/p&gt;
&lt;p&gt;Once I built the arm2pulumi coverage tracker end-to-end, I shifted to tf2pulumi. Unlike &lt;code&gt;arm2pulumi&lt;/code&gt;, there was no code to inherit, and I had to write out the entire workflow from scratch. The Go program was the real challenge, as the CI work and cloud infrastructure I had written was reusable. I got a much better hang of Go as a language and the advantages that came with it. I also got to leverage Pulumi’s &lt;a href="https://www.pulumi.com/docs/using-pulumi/automation-api/"&gt;Automation API&lt;/a&gt; and the power of having multiple, configurable stacks through Pulumi to significantly simplify the process of deploying &lt;code&gt;tf2pulumi&lt;/code&gt;’s (and any other converter’s) coverage report cloud infrastructure. Overall, I explored various new technologies, many of which I’ve used in personal projects since, and plan to continue to do so.&lt;/p&gt;
&lt;h2 id="day-to-day-work"&gt;Day to Day Work&lt;/h2&gt;
&lt;p&gt;Due to the ongoing pandemic, my internship was done fully remote. Having come from 4 quarters of remote learning in college, I wasn’t particularly ecstatic about more remote work. Pulumi completely exceeded my expectations, though! It was hard to meet new people, and I missed out on the daily interactions you might expect in a traditional office environment. Regardless, efforts were made to overcome that, and they were pretty successful, with biweekly random 1:1s and fun team events to better integrate with the team. On the other hand, I work better at night and am a bit of a late sleeper, so I could adjust my schedule to my strengths more than I would if I were going into an office each day. Additionally, Pulumi has adapted nicely to the remote environment and made my experience much better than I thought possible.&lt;/p&gt;
&lt;p&gt;The team itself was great, with everyone being super friendly and supportive. It took me longer than I expected to get the confidence to ask questions in general Slack channels, but each time I did, I was met with a helpful response and got the assistance I needed to succeed. Despite being the only intern, I never felt cast aside and was guided throughout my project in a balanced way, still allowing for some independence. Everyone is also so knowledgeable that I would learn something new perusing Slack every day, whether internal to Pulumi or an article about some new way of doing things.&lt;/p&gt;
&lt;p&gt;Thanks to the high level of transparency at Pulumi, I also got to see many different levels of the company, rather than just the work that I was doing. As a result, I learned more about how a company works fundamentally, and a typical development process.&lt;/p&gt;
&lt;h2 id="closing-thoughts"&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;Pulumi was my first ever internship, and I couldn’t have asked for a better experience. I learned about a ton of new technologies, some of which I may not have explored yet but at least am aware of for future projects. In addition, I met some truly incredibly talented, hardworking, and interesting people. I’m stoked to continue using Pulumi and am excited to see how the company evolves and grows!&lt;/p&gt;
&lt;h2 id="thank-yous"&gt;Thank Yous&lt;/h2&gt;
&lt;p&gt;First off, a huge shout out to the leadership at Pulumi for offering this opportunity to begin with! Thanks to &lt;a href="https://github.com/leezen"&gt;Lee&lt;/a&gt;, especially for organizing the internship and your help throughout it!&lt;/p&gt;
&lt;p&gt;Thank you to &lt;a href="https://github.com/lblackstone"&gt;Levi&lt;/a&gt; for being an awesome, approachable mentor and always willing to help out! I asked a ton of &amp;ndash; oftentimes pretty random &amp;ndash; questions, and you helpfully answered each of them.&lt;/p&gt;
&lt;p&gt;Thank you to &lt;a href="https://github.com/viveklak"&gt;Vivek&lt;/a&gt; for guiding me through many technical details and approving my PRs. Your guidance was really useful, and I appreciate it a lot!&lt;/p&gt;
&lt;p&gt;Lastly, thanks to all those who helped me out along the way and the rest of the team for building such a friendly, helpful environment!&lt;/p&gt;</description><author>Hitesh Boinpally</author><category>pulumi-interns</category></item><item><title>Testable IAM Policy Documents</title><link>https://www.pulumi.com/blog/testable-iam-policy-documents/</link><pubDate>Wed, 12 May 2021 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/testable-iam-policy-documents/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/testable-iam-policy-documents/index.png" /&gt;
&lt;p&gt;I was relieved to find Pulumi. Finally, we have testable Infrastructure as Code. We can write fast unit tests that we can execute locally without needing the cloud. However, I was a bit disappointed. Pulumi does not have a full representation of IAM Policy documents. Fortunately, it was relatively easy to build a library that did this!&lt;/p&gt;
&lt;p&gt;Policy documents are assigned using JSON objects that should follow the AWS
IAM JSON Policy syntax.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;My test policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;: &lt;span class="kt"&gt;JSON.stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2012-10-17&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ec2:Describe*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, it is perfectly possible to pass an invalid IAM Policy document because there is no validation. You will only notice if it is invalid the minute the policy is applied in the AWS cloud. That creates an unreasonably long feedback loop, incurring a significant amount of waiting and time to correct.&lt;/p&gt;
&lt;p&gt;To avoid this, I prefer to write my policies as Policy as Code. It avoids
common syntax errors, reduces the feedback cycle, and increases
your delivery throughput.&lt;/p&gt;
&lt;p&gt;Having to pass a JSON as a policy document did not feel optimal.&lt;/p&gt;
&lt;p&gt;I work in the financial industry, and compliance is important. So, I searched for something that allowed me to easily unit test IAM Policy documents, preferably at the Statement level,to help us adhere to security requirements.&lt;/p&gt;
&lt;p&gt;Before reinventing the wheel, I searched for existing packages in
JavaScript for manipulating IAM Policy documents.&lt;/p&gt;
&lt;p&gt;Pulumi has the &lt;a href="https://www.pulumi.com/registry/packages/aws/api-docs/iam/getpolicydocument"&gt;&lt;code&gt;aws.iam.getPolicyDocument&lt;/code&gt;&lt;/a&gt; API. That looked interesting because it allows writing the policies as Policy as Code. But you cannot properly unit test the IAM Policy document produced by
&lt;code&gt;aws.iam.getPolicyDocument&lt;/code&gt; function. When Pulumi runs in testing mode, that function is not available unless you mock it. Huh. That is not very helpful.&lt;/p&gt;
&lt;p&gt;I dug further to find Node.js packages for manipulating IAM Policy documents. Not much. Except for &lt;a href="https://docs.aws.amazon.com/cdk/api/latest/typescript/api/aws-iam.html"&gt;AWS CDK&lt;/a&gt;. But you must drag the whole CDK Node.js package into your project only to handle IAM Policy documents. But, the AWS CDK was a good starting point for designing &lt;a href="https://github.com/thinkinglabs/aws-iam-policy"&gt;@thinkinglabs/aws-iam-policy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="a-simple-identity-based-policy"&gt;A simple identity-based policy&lt;/h2&gt;
&lt;p&gt;Let us look at the code sample on &lt;code&gt;pulumi.com&lt;/code&gt; for
&lt;a href="https://www.pulumi.com/registry/packages/aws/api-docs/iam/policy/"&gt;&lt;code&gt;aws.iam.Policy&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;My test policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;: &lt;span class="kt"&gt;JSON.stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2012-10-17&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ec2:Describe*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using &lt;code&gt;@thinkinglabs/aws-iam-policy&lt;/code&gt;, that would look as follows.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@thinkinglabs/aws-iam-policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;My test policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;: &lt;span class="kt"&gt;grantEC2Describe&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;grantEC2Describe() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ec2:Describe*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To test if the IAM Policy is a valid identity-based policy, we can use &lt;code&gt;PolicyDocument.validateForIdentityPolicy()&lt;/code&gt;, which returns an array of &lt;code&gt;string&lt;/code&gt; error messages. If it returns an empty array, the IAM Policy is valid.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chai&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./mocks&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@pulumi/pulumi&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@thinkinglabs/aws-iam-policy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;sut&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../src/index&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;get&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.Output&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="na"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;IAM Policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;should be a valid identity-based policy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validateForIdentityPolicy&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="a-more-complex-resource-based-policy"&gt;A more complex resource-based policy&lt;/h2&gt;
&lt;p&gt;As a regulated industry, we are required to closely control who has access to what. What scares us most is to inadvertently grant a right to someone that could result in non-compliance, for instance, granting delete S3 bucket rights or granting access to confidential information stored in an S3 Bucket.&lt;/p&gt;
&lt;p&gt;To avoid this, we make extensive use of S3 Bucket policies composed of several statements granting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;admin access to administrators,&lt;/li&gt;
&lt;li&gt;usage access to users&lt;/li&gt;
&lt;li&gt;and denying delete bucket rights for everyone.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let us create an S3 Bucket with a Bucket Policy having multiple Statements.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AnonymousUserPrincipal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RootAccountPrincipal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@thinkinglabs/aws-iam-policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adminRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin-role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;assumeRolePolicy&lt;/span&gt;: &lt;span class="kt"&gt;createAssumeRolePolicy&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user-role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;assumeRolePolicy&lt;/span&gt;: &lt;span class="kt"&gt;createAssumeRolePolicy&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bucket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;acl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;private&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucketPolicy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BucketPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bucketPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;: &lt;span class="kt"&gt;bucket.id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;: &lt;span class="kt"&gt;createS3BucketPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0123456789012&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;adminRole&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userRole&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createAssumeRolePolicy() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;RootAccountPrincipal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;123412341234&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sts:AssumeRole&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createS3BucketPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;accountId&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;: &lt;span class="kt"&gt;aws.s3.Bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucketAdmins&lt;/span&gt;: &lt;span class="kt"&gt;aws.iam.Role&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucketUsers&lt;/span&gt;: &lt;span class="kt"&gt;aws.iam.Role&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucketAdmins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;bucketUsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucketAdminUniqueIds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucketUserUniqueIds&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow access for Bucket Administrators&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Deny&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AnonymousUserPrincipal&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;s3:PutBucketPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;s3:GetBucketPolicy*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;s3:DeleteBucketPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;StringNotLike&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;aws:userId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketAdminUniqueIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;:*`&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow use of the bucket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Deny&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AnonymousUserPrincipal&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;s3:ListBucket*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;s3:Get*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;s3:PutObject*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;s3:DeleteObject*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/*`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;StringNotLike&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;aws:userId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketAdminUniqueIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;:*`&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketUserUniqueIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;uniqueId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;:*`&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Deny delete bucket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Deny&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AnonymousUserPrincipal&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;s3:DeleteBucket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To test if the S3 Bucket Policy allows access for bucket administrators, we need to check if a Statement is present in the Policy and test the content of that single Statement.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@thinkinglabs/aws-iam-policy&lt;/code&gt; provides the ability to retrieve a single
Statement by its &lt;code&gt;Sid&lt;/code&gt; if one was provided.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStatement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MyFancySID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let us test if the S3 Bucket Policy grants admin rights for administrators by checking if the Policy contains the Statement &amp;ldquo;&lt;em&gt;Allow access for Bucket Administrators&lt;/em&gt;&amp;rdquo;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chai&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./mocks&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AnonymousUserPrincipal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@thinkinglabs/aws-iam-policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;S3 Bucket Policy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accountId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;123456789012&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;a-bucket&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adminRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin-role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;assumeRolePolicy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user-role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;assumeRolePolicy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createS3BucketPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;adminRole&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userRole&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;: &lt;span class="kt"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;should allow access for Bucket Administrators&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStatement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Allow access for Bucket Administrators&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;s3:PutBucketPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;s3:GetBucketPolicy*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;s3:DeleteBucketPolicy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Deny&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AnonymousUserPrincipal&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;a-bucket-arn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;StringNotLike&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;aws:userId&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;123456789012&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;admin-role-unique-id:*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow access for Bucket Administrators&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The test needs some fake IAM Roles. This is achieved by including a &lt;code&gt;mocks&lt;/code&gt; module.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@pulumi/pulumi&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMocks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;newResource&lt;/span&gt;: &lt;span class="kt"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.runtime.MockResourceArgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;: &lt;span class="kt"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;-arn`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;args.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;aws:iam/role:Role&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;defaultState&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;uniqueId&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;-unique-id`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resourceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;-id`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;: &lt;span class="kt"&gt;resourceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;: &lt;span class="kt"&gt;defaultState&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;call&lt;/span&gt;: &lt;span class="kt"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.runtime.MockCallArgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ideas-for-future-improvements"&gt;Ideas for future improvements&lt;/h2&gt;
&lt;p&gt;At the moment, &lt;code&gt;Condition&lt;/code&gt; accepts any JSON object. Valid or not, it will serialize the object to JSON as-is. To avoid building an invalid &lt;code&gt;Condition&lt;/code&gt; element, I am planning to add an object model for this. The API would look something like this.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Deny&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Condition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;StringNotLike&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws:userId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;userId1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;userId2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I am also planning to add validation for &lt;code&gt;Sid&lt;/code&gt;s. According to the AWS IAM documentation, a &lt;code&gt;Sid&lt;/code&gt; only accepts alphanumerical characters &lt;code&gt;[a-zA-Z0-9]&lt;/code&gt;. But I see that resource-based Policies for some services accept spaces for &lt;code&gt;Sid&lt;/code&gt;s. AWS does not document this. Although the documentation for &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-4"&gt;S3 Bucket Policies&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default"&gt;KMS Key Policies&lt;/a&gt; clearly show examples with spaces for &lt;code&gt;Sid&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;The library does not support &lt;code&gt;NotPrincipal&lt;/code&gt;, &lt;code&gt;NotAction&lt;/code&gt;, and &lt;code&gt;NotResource&lt;/code&gt;
because I did not need them at the time. At some point, I will add support for
that too.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As you can see, you can extend a Pulumi program with existing Node modules or write your own. By testing IAM policies before deployment, we can avoid errors before deployments and provide guardrails for developers.&lt;/p&gt;</description><author>Thierry de Pauw</author><category>aws</category><category>iam</category></item><item><title>Cloud Engineering: The Future Is Now</title><link>https://www.pulumi.com/blog/cloud-engineering-the-future-is-now/</link><pubDate>Thu, 29 Apr 2021 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/cloud-engineering-the-future-is-now/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/cloud-engineering-the-future-is-now/index.png" /&gt;
&lt;p&gt;Thank you for joining the PulumiUP event. We had a stellar set of speakers and panelists discussing the future of DevOps and how Cloud Engineering is providing the tools and processes that enable faster delivery, the right mix of architecture, and foster collaboration among teams in an organization. Here are some of the highlights and takeaways from our speakers.&lt;/p&gt;
&lt;h2 id="putting-cloud-engineering-in-practice"&gt;Putting Cloud Engineering in Practice&lt;/h2&gt;
&lt;p&gt;Our speakers all commented on how the cloud is speeding up development. Applications are dynamic, and your infrastructure should also be dynamic, according to Adrian Cockcroft, VP of Sustainability Architecture at Amazon. The future of infrastructure is a mixture of lightweight, scalable services combined with event-driven architecture. Furthermore, composing infrastructure should take advantage of well-architected frameworks such as those published by AWS and Liberty Mutual.&lt;/p&gt;
&lt;p&gt;Underscoring this, Justin Fitzhugh, VP of Cloud Engineering at Snowflake, cited the need to disaggregate compute and storage to scale independently. Moreover, Snowflake needed to scale across three public clouds with self-managed infrastructure. In Snowflake&amp;rsquo;s experience, scaling with manual processes was not a viable option. They codified actions by following the software engineering process of code commits, tests, CI processes, and a CD pipeline for execution.&lt;/p&gt;
&lt;p&gt;Keith Redmond, VP of SaaS Engineering at Fernergo share a perspective from the financial services industry. He reiterated the need for a deployment framework that bridged dev and ops teams and an automated build and release process to maintain integrity and reliability. He noted that this required a change in culture from teams handing off tasks to each other without input from the other to a completely integrated team where all actions with infrastructure begin with a code commit. The culture shift to an engineering-managed process also changed hiring patterns from operators and system administrators with some coding skills to software engineers interested in infrastructure.&lt;/p&gt;
&lt;p&gt;In the current cloud engineering landscape, we will continue to see movement towards heterogeneous architectures, an increase in the use of software engineering methodologies to deploy infrastructure, and more automation for building and deploying in the cloud. This segues into the future of cloud engineering with a focus on tooling, process, and teams.&lt;/p&gt;
&lt;h2 id="the-future-of-cloud-engineering"&gt;The Future of Cloud Engineering&lt;/h2&gt;
&lt;p&gt;The cloud engineering panel included Justin Fitzhugh, Dana Lawson, VP of Engineering at GitHub, Charity Majors, CTO at Honeycomb, and was moderated by Kat Cosgrove, Developer Advocate at JFrog. The session, titled &amp;ldquo;Your Peers,&amp;rdquo; discussed the future of cloud engineering.&lt;/p&gt;
&lt;p&gt;When planning for the future of modern cloud applications, the panel agreed that the industry would continue to iterate and evolve away from domain specific languages, DSLs, and towards software engineering practices for infrastructure. They also agreed that while &lt;strong&gt;Go&lt;/strong&gt; would be the most popular language for Infrastructure as Code, Ruby and JavaScript will also continue to be key languages.&lt;/p&gt;
&lt;p&gt;Cloud engineering personas will change as new technologies such as the Internet of Things, availability of 5G, orchestration, edge computing, and future network APIs roll out. Cloud engineers should continue to focus on containers and what goes into applications. Knowing the entire lifecycle of their application from development to production is a must for cloud engineers. It underlies the concept of a single persona that can use services to compose development and services. Ultimately, the job of the cloud engineer is to reduce complexity and reduce friction in the pipeline by using patterns as needed and building platforms and tools consistently.&lt;/p&gt;
&lt;p&gt;The panel discussed the reality of testing in production. Charity Majors highlighted that you have no choice, whether you admit it or not; there will always be known unknowns because devs or operators cannot test everything. Software will always have bugs, but the problem can be managed by having more ways to separate problems and test them in a small and controlled way. Testing in production begins with observability, starting with usual tools such as &lt;code&gt;strace&lt;/code&gt; and other enhanced toolsets to inspect your code. Also, feature flags and deployment models help find bugs and limit their impact when applications go into production.&lt;/p&gt;
&lt;p&gt;Finally, the panel looked backward at the impact and legacy of devops. The panel agreed that devops brought both sides to the table. Operations learned about code and applications while developers learned about infrastructure. Practitioners are software engineers, but each with a different focus. Implementing infrastructure is similar to creating a new feature. However, there is a concern for losing deep systems knowledge, and software engineers are unlikely to have a deep understanding of networking, system administration, or storage. The solution is to train people cross-functionally, i.e., software engineers on systems and operators on coding and application. Teamwork is the key to breaking down operational and knowledge silos in an organization.&lt;/p&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;p&gt;Thank you for attending PulumiUP! Your response to the &lt;a href="https://www.pulumi.com/blog/pulumi-3-0/"&gt;Pulumi 3.0 release&lt;/a&gt; was overwhelming. If you didn&amp;rsquo;t have the chance to catch PulumiUP on launch day, you can watch the entire event.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Zko70KVGcgo?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;</description><author>Sophia Parafina</author><category>cloud-engineering</category></item><item><title>PulumiUP: the Event for Cloud Engineers</title><link>https://www.pulumi.com/blog/pulumiup/</link><pubDate>Wed, 14 Apr 2021 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumiup/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumiup/index.png" /&gt;
&lt;p&gt;My professional background has included nearly ten years of managing field events and user conferences. I never thought I would say this, but I miss traveling. I even missed Vegas and AWS re:Invent this year. I miss connecting with customers and advocates in our communities. I wish we could all be looking forward to getting together in person in Seattle or Austin or &lt;em&gt;insert any city here&lt;/em&gt;. As the year continued, it became clear we were not going back to in-person events anytime soon, and everyone in the industry pivoted to virtual programs while video conferencing became an all-day activity.&lt;/p&gt;
&lt;p&gt;We spent a lot of time considering how to best engage and share announcements with our community and encourage the cloud engineering community&amp;rsquo;s growth. All of us here at Pulumi recognize how valuable your time is and how much time we&amp;rsquo;ve all spent on virtual event platforms in the last year. With that in mind, we made a deliberate decision to avoid any all-day or multi-day programming. Instead, we are hosting a short 2-hour keynote that we think you will find insightful and valuable, with best practices and real-life situations that you can learn from and apply to your approach to building, delivering, and managing modern cloud applications.&lt;/p&gt;
&lt;p&gt;&lt;img src="pulumiup.png" alt="PulumiUP"&gt;&lt;/p&gt;
&lt;p&gt;PulumiUP Agenda - Kicking off on 4/20 at 9 am - 11 am PST - &lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Save your spot&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Speakers&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Title and Company&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Subject&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Joe Duffy&lt;/td&gt;
&lt;td&gt;Co-Founder and CEO, Pulumi&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;The Modern Cloud Era: All Software is Cloud Software&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adrian Cockcroft &amp;amp; Aaron Kao&lt;/td&gt;
&lt;td&gt;VP of Sustainability Architecture, Amazon VP of Marketing, Pulumi&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Discussion: What’s different about building in a modern cloud application world&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Justin Fitzhugh&lt;/td&gt;
&lt;td&gt;VP of Cloud Engineering, Snowflake&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Perspectives from Cloud Engineering Pioneers&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keith Redmond&lt;/td&gt;
&lt;td&gt;VP of SaaS Engineering, Fenergo&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Perspectives from Cloud Engineering Pioneers&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Luke Hoban&lt;/td&gt;
&lt;td&gt;CTO, Pulumi&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Placing Cloud Engineering in the Hands of Every Developer&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sophia Parafina&lt;/td&gt;
&lt;td&gt;Technical Marketing Manager, Pulumi&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Komal Ali&lt;/td&gt;
&lt;td&gt;Software Engineer&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Panel: Hear from the Experts: Planning for the Future of Modern Cloud Applications&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Title and Company&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Moderator: Kat Cosgrove&lt;/td&gt;
&lt;td&gt;Developer Advocate, JFrog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Justin Fitzhugh&lt;/td&gt;
&lt;td&gt;VP of Cloud Engineering, Snowflake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Charity Majors&lt;/td&gt;
&lt;td&gt;CTO/Co-Founder, Honeycomb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dana Lawson&lt;/td&gt;
&lt;td&gt;VP of Engineering, GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Engineering leadership from Snowflake, the cloud data warehousing organization, and Fenergo, a client lifecycle management provider for the financial services industry, will share their perspectives and experiences practicing cloud engineering for the modern cloud era. Justin Fitzhugh, VP of Cloud Engineering at Snowflake, and Keith Redmond, VP of SaaS Engineering at Fenergo, will each share how they reduced costs while empowering every developer on their team.&lt;/p&gt;
&lt;p&gt;Everyone at Pulumi is super excited to be sharing this material with our community. If you are interested in cloud engineering, cloud infrastructure, software development, modern applications, or Pulumi, you want to save your spot for this 2-hour event. Whether you’re a seasoned cloud engineer or just curious to learn what’s all the fuss about cloud engineering, you will learn something new about the future of building on the cloud at PulumiUP. You can also sign up for new workshops and other events occurring in April and May. We’ll miss seeing you in person but hope that changes soon! Pulumipus and I are packing our bags and hoping for the best.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/pulumi-up/"&gt;Save your spot today!&lt;/a&gt;&lt;/p&gt;</description><author>Wendy Smith</author><category>cloud-engineering</category><category>pulumi-events</category></item><item><title>Observability with Infrastructure as Code</title><link>https://www.pulumi.com/blog/observability-with-infrastructure-as-code/</link><pubDate>Fri, 26 Feb 2021 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/observability-with-infrastructure-as-code/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/observability-with-infrastructure-as-code/index.png" /&gt;
&lt;p&gt;&lt;strong&gt;Guest Article:&lt;/strong&gt; &lt;a href="https://andydote.co.uk"&gt;Andy Davies&lt;/a&gt; is a Senior Software Developer at &lt;a href="https://reaktor.com"&gt;Reaktor&lt;/a&gt;,
a tech company based in Amsterdam, New York, and Finland, writing about using the Pulumi Automation API to add
observability to infrastructure provisioning.&lt;/p&gt;
&lt;p&gt;When using the &lt;a href="https://www.pulumi.com/blog/tag/automation-api/"&gt;Pulumi Automation API&lt;/a&gt; to create applications that
provisions infrastructure, it is very handy to use observability techniques to ensure the application functions
correctly and to find where performance bottlenecks are.&lt;/p&gt;
&lt;p&gt;One of the applications I work on creates a VPC and Bastion host and then stores the credentials in a Vault instance.
The problem is that the &amp;lsquo;create infrastructure&amp;rsquo; part is an opaque blob, in that I can see it takes 129 seconds to create,
but I can’t see what it’s doing or why it takes this amount of time.&lt;/p&gt;
&lt;p&gt;&lt;img src="before.png" alt="honeycomb traces of one pulumi stack resource"&gt;&lt;/p&gt;
&lt;p&gt;So can I do better?&lt;/p&gt;
&lt;h3 id="the-initial-application"&gt;The Initial Application&lt;/h3&gt;
&lt;p&gt;In this example, I use &lt;a href="https://honeycomb.io/"&gt;Honeycomb&amp;rsquo;s&lt;/a&gt; &lt;a href="https://github.com/honeycombio/beeline-go/"&gt;Go Beeline&lt;/a&gt; to
capture all the data I care about; durations, errors, and any context which is &amp;lsquo;interesting&amp;rsquo;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;WriteKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;HONEYCOMB_API_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;pulumi-demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;basic-vpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FullyQualifiedStackName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;PULUMI_USERNAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;basic-vpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UpsertStackInlineSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;basic-vpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;azs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getAvailabilityZones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewVpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VpcArgs&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;BaseCidr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;192.168.0.0/16&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AvailabilityZoneNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;azs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;S3Endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DynamoEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;aws:region&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ConfigValue&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;PULUMI_REGION&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)});&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Workspace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;v3.23.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;optup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProgressStreams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;//vault code&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="adding-infrastructure-observability"&gt;Adding Infrastructure Observability&lt;/h3&gt;
&lt;p&gt;To get a handle on what happens when &lt;code&gt;stack.Up()&lt;/code&gt; runs, I have implemented a custom &lt;code&gt;io.Writer&lt;/code&gt;, which is
passed into the &lt;code&gt;ProgressStream&lt;/code&gt; constructor.&lt;/p&gt;
&lt;p&gt;The custom progress stream&amp;rsquo;s &lt;code&gt;Write&lt;/code&gt; method is called once for each line emitted, which allows us to start new spans
when a resource starts being constructed, and send them when construction completes. This is currently achieved by
parsing the console output text, but I gather in the future, it will be possible to get streamed JSON blobs that can
be unmarshaled into go structs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pulumiBeeline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;contexts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewPulumiBeeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;pulumiBeeline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;pulumiBeeline&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;contexts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(){},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;pulumiBeeline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// todo: make more robust, support modifications, deletions etc.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;strings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TrimSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;strings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;//+ aws-vpc dev creating&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;//+ &amp;lt;type&amp;gt; &amp;lt;name&amp;gt; &amp;lt;action&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceAction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceAction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;creating&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// add other things here&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contexts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Send&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;resourceAction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;created&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contexts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;resourceName&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Modifying the &lt;code&gt;optup.ProgressStreams&lt;/code&gt; is the only change needed to the original application:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;optup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ProgressStreams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewPulumiBeeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;beeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;err&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When I rerun this program, I can see a lot more information in my Honeycomb traces, which shows me
that Pulumi is &lt;em&gt;highly&lt;/em&gt; parallelized and provides a better idea of where the time is spent when creating
infrastructure. In this example, it’s the NAT Gateways:&lt;/p&gt;
&lt;p&gt;&lt;img src="after.png" alt="honeycomb traces of all infrastructure resources in the pulumi stack"&gt;&lt;/p&gt;
&lt;p&gt;In the future, I want to expand this to cover far more details. Among those details are why resources were
created/modified/destroyed and collecting more information on what causes resources to fail.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;In the end, this turned out to be much easier to achieve than I had hoped. Using Pulumi programmatically was a huge
productivity boost, instead of running &lt;code&gt;os.Exec&lt;/code&gt; directly.&lt;/p&gt;
&lt;p&gt;I am looking forward to all the new kinds of tooling I can build to solve my user&amp;rsquo;s problems by continuing to utilize
Honeycomb for my observability and Pulumi for my infrastructure.&lt;/p&gt;</description><author>Andy Davies</author><category>guest-post</category><category>automation-api</category><category>observability</category><category>honeycomb</category></item><item><title>Upcoming Workshops and Events</title><link>https://www.pulumi.com/blog/upcoming-events-2021-jan-march/</link><pubDate>Tue, 12 Jan 2021 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/upcoming-events-2021-jan-march/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/upcoming-events-2021-jan-march/index.png" /&gt;
&lt;p&gt;It&amp;rsquo;s a new year and it&amp;rsquo;s time to level up your cloud engineering skills. Pulumi is there to get you started on your cloud engineering journey with workshops and technical sessions.&lt;/p&gt;
&lt;h2 id="cicd-pipelines-for-kubernetes-apps-with-pulumi--codefresh"&gt;CI/CD Pipelines for Kubernetes Apps with Pulumi &amp;amp; Codefresh&lt;/h2&gt;
&lt;p&gt;To kickoff the year we start with a technical session that demonstrates how to continuously deliver both applications and provision infrastructure using Codefresh CI/CD. This session will demonstrate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The basics of CI/CD using Codefresh.&lt;/li&gt;
&lt;li&gt;How to declare cloud resources using Pulumi and your favorite programming languages.&lt;/li&gt;
&lt;li&gt;How to define a simple pipeline for Kubernetes deployments.&lt;/li&gt;
&lt;li&gt;Practical tests to ensure infrastructure reliability as part of your pipeline.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Taught by Pulumi and Codefresh engineers, you&amp;rsquo;ll receive a thorough understanding of CI/CD and infrastructure as code best practices.&lt;/p&gt;
&lt;h2 id="intro-to-pulumi"&gt;Intro to Pulumi&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re new to infrastructure as code, this workshop is for you. You will learn the fundamentals of Infrastructure as Code through a series of guided exercises using Pulumi’s Cloud Engineering platform. The workshop covers setting up Pulumi, an infrastructure as code platform that uses programming languages to provision modern cloud infrastructure.&lt;/p&gt;
&lt;p&gt;This workshop is designed to help users completely new to Pulumi become familiar with the core concepts needed to be effective with the Pulumi Infrastructure as Code platform. We will guide through the Pulumi platform with diagrams and a series of hands on exercises to help you understand the building blocks available in Pulumi.&lt;/p&gt;
&lt;p&gt;The workshop will cover the following topics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is Pulumi?&lt;/li&gt;
&lt;li&gt;How to install Pulumi&lt;/li&gt;
&lt;li&gt;Configuring your development environment&lt;/li&gt;
&lt;li&gt;Choose your Pulumi language&lt;/li&gt;
&lt;li&gt;An introduction to the Pulumi state &amp;amp; the Pulumi Service&lt;/li&gt;
&lt;li&gt;An introduction to Pulumi config&lt;/li&gt;
&lt;li&gt;Storing sensitive data in Pulumi securely&lt;/li&gt;
&lt;li&gt;Provision your first resources&lt;/li&gt;
&lt;li&gt;Understanding stacks&lt;/li&gt;
&lt;li&gt;An introduction to the Pulumi programming model&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We have multiple workshops scheduled from January to March. Register for one today.&lt;/p&gt;
&lt;p&gt;Jan 26: Intro to Pulumi, 9 AM PST
Feb 9: Intro to Pulumi, 9 AM PST
Feb 23: Intro to Pulumi, 9 AM PST
March 9: Intro to Pulumi, 9 AM PST&lt;/p&gt;
&lt;h2 id="deploying-microservices-with-pulumi-and-aws-lambda"&gt;Deploying Microservices with Pulumi and AWS Lambda&lt;/h2&gt;
&lt;p&gt;This serverless workshop demonstrates how Pulumi can accelerate provisioning of cloud infrastructure. The workshop shows how to build a set of microservices utilizing AWS’s newest Lambda features. Attendees will be guided through the process of provisioning a set of Lambda resources in AWS and see real time examples of how Pulumi’s innovative programming model helps turbocharge cloud engineering.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re an active Pulumi user and building serverless applications this hands-on workshop is for you. You will learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to provision a Lambda function in AWS.&lt;/li&gt;
&lt;li&gt;How to provision infrastructure such as DynamoDB &amp;amp; API Gateway to support your microservice applications.&lt;/li&gt;
&lt;li&gt;How to take advantage of the newest Lambda features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sign up to learn about one of the major cloud technologies.&lt;/p&gt;
&lt;h2 id="building-a-kubernetes-platform-in-amazon-eks-with-pulumi"&gt;Building a Kubernetes Platform in Amazon EKS with Pulumi&lt;/h2&gt;
&lt;p&gt;Kubernetes is one of the major cloud technologies and in this hands-on workshop, we’ll examine how Pulumi works with Kubernetes through real-world examples of managing Amazon EKS clusters. We’ll focus on building a user-friendly Kubernetes platform, installing software that makes Kubernetes easy to use for application developers.&lt;/p&gt;
&lt;p&gt;Attendees will be guided through the process of provisioning an Amazon EKS cluster and installing platform friendly software such as the aws load balancer controller. We&amp;rsquo;ll cover the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How-to provision a production-ready Amazon EKS cluster with key features enabled using Pulumi&lt;/li&gt;
&lt;li&gt;Provisioning the aws-load-balancer-controller to automate ingress creation&lt;/li&gt;
&lt;li&gt;Install an example application to show the end-to-end user experience for users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Get a solid foundation for provisioning Kubernetes clusters and applications by signing up.&lt;/p&gt;</description><author>Sophia Parafina</author><category>pulumi-events</category><category>kubernetes</category><category>serverless</category></item><item><title>Zephyr's Summer Intern Experience with Pulumi</title><link>https://www.pulumi.com/blog/zephyrs-summer-intern-experience-with-pulumi/</link><pubDate>Fri, 18 Sep 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/zephyrs-summer-intern-experience-with-pulumi/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/zephyrs-summer-intern-experience-with-pulumi/index.png" /&gt;
&lt;p&gt;Hi, I am &lt;a href="https://www.linkedin.com/in/zephyr-zhou-a17741196/"&gt;Zephyr Zhou&lt;/a&gt;, a senior Computer Science student at the University of Washington. I spent this past summer interning at Pulumi. This is my first internship ever in my life. Thanks to Pulumi for providing this opportunity even in this difficult time of the Covid-19 epidemic. Despite the sad truth that I couldn&amp;rsquo;t get in touch offline, I believe this will be one of my most precious memories.&lt;/p&gt;
&lt;p&gt;Time goes by so fast, but before saying goodbye to my internship, I would like to share the story.&lt;/p&gt;
&lt;h2 id="personal-growth"&gt;Personal Growth&lt;/h2&gt;
&lt;p&gt;Honestly, before my internship started, I was so nervous that I couldn&amp;rsquo;t sleep. Previously, I had taken only one data management course that contains a tutorial about setting up Azure SQL Database. Other than that, I knew nothing about the cloud. Although I have read the &lt;a href="https://www.pulumi.com/docs/quickstart"&gt;Getting Started documentation&lt;/a&gt; and learned Go, I was worried that my understanding was not good enough. Also, I transferred from a community college to the University of Washington as a junior student and was admitted to the Computer Science major after that. Therefore, I felt relatively new to programming than my peers and less confident working in the industry, even less so working remotely.&lt;/p&gt;
&lt;p&gt;However, I am glad that I was brave enough to make the first step out of my comfort zone to learn about new things and improve my understanding while practicing. That was one of the important reasons for choosing to intern at Pulumi, a startup with great potential. Also, due to the nature of startups, Pulumi has smaller but more connected teams. Personally, I felt more comfortable discussing issues and thoughts in small groups. Also, I was able to work with different teams and people. I was also able to broaden my horizons and improve my collaboration skills.&lt;/p&gt;
&lt;p&gt;I found that the more familiar I got with the company and the job, the more confident I was. My confidence was boosted in large part from the support of team members. The warm greetings and kind help gave me a lot of powers and courage. Working remotely with Pulumi was much more interactive than I thought. The one-to-one meeting with my mentor and site supervisor has boosted my working efficiency because I could compile my questions and updates, talk about them all together, and get informed about if I am on the right path. I also loved the fact that I was able to join other team meetings so I could learn about the different projects other people are working on.&lt;/p&gt;
&lt;p&gt;In addition, I absolutely loved the various team-building games, especially the virtual escape room and the pair-up chatting with other engineers in the team. These interesting events and relaxed atmosphere made me feel more welcomed and less stressful. I&amp;rsquo;ve been moved and realized it is okay to be imperfect and improve step by step. Despite having less coding experience, I was still welcomed and cared for by everyone at Pulumi.&lt;/p&gt;
&lt;p&gt;Moreover, I am so glad that I could work on my individual internship project: building the content management system (CMS) for Pulumi&amp;rsquo;s website. I took control of the whole development phase of the Content Management System project. I was able to research and write up proposals, implement the project, plan the next steps, and improve. In the end, the CMS was published and running. I have contributed back to the Netlify CMS, the underlying technology for the CMS. I have built an &lt;a href="https://github.com/pulumi/examples/tree/master/aws-ts-netlify-cms-and-oauth"&gt;open-source example&lt;/a&gt; and written blog posts on deploying the &lt;a href="https://www.pulumi.com/blog/deploying-netlify-cms-on-aws/"&gt;CMS application&lt;/a&gt; and its &lt;a href="https://www.pulumi.com/blog/deploying-the-infrastructure-of-oauth-server-for-cms-app/"&gt;OAuth Access Token Server&lt;/a&gt; to AWS.&lt;/p&gt;
&lt;p&gt;When I heard the CMS project would be a great help for the marketing team during our meetings, I felt indescribable happiness and proud of myself. Although far from perfect, I was finally able to prove myself with this unforgettable experience.&lt;/p&gt;
&lt;p&gt;Confidence is the greatest gift that Pulumi gave me during this Summer internship. I felt a lot more confident in entering the technology industry and pursue my career goal as a software engineer. Thanks to this internship experience, I have grown braver and stronger than before.&lt;/p&gt;
&lt;h2 id="technology-skills"&gt;Technology Skills&lt;/h2&gt;
&lt;p&gt;I have learned a lot of skills that I have never learned in the classrooms.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;First of all, I learned a lot about Pulumi and cloud technology.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before my internship, I read about how Pulumi provides a platform for building infrastructure. At first, I thought the benefit would be to reduce the amount of work to click through different settings on the provider&amp;rsquo;s website. However, during the CMS development process, I found writing infrastructure as code can do many more things than that. For example, I have implemented Github Actions, which automatically deploys the infrastructure when I push or merge a pull request. It saves time to upload and deploy again and prevent any manual error by automating the process. Also, if we want to remove the cloud resources completely, Pulumi enables us to do a simple &lt;code&gt;pulumi destroy&lt;/code&gt; rather than manually going through and worrying about missing any resources.&lt;/li&gt;
&lt;li&gt;I also learned to build the cloud infrastructure for a static website by configuring AWS S3 bucket, Route 53, CloudFront, and Certificate Manager. I also learned to configure AWS Fargate Service and create a Dockerfile.&lt;/li&gt;
&lt;li&gt;I learned more concepts, including assume role, CDN (Content Delivery Network), target groups, and load balancers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Besides cloud technology, I also got to work with the Continuous Integration/Continuous Delivery concept and have practiced it with GitHub to work with the team.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I learned more details about git command including, the difference between &lt;code&gt;git rebase&lt;/code&gt; and &lt;code&gt;git merge&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I learned to create GitHub projects, issues, and pull requests and link them for better references.&lt;/li&gt;
&lt;li&gt;I got to know about GitHub Actions and Workflow and implemented one for my internship project to increase efficiency in deploying.&lt;/li&gt;
&lt;li&gt;I learned about GitHub OAuth Applications and more about GitHub API while working on the OAuth Server for the CMS application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I learned to create a static website using plain HTML and CSS in the classroom. During my internship, I was able to get in touch with modern front-end technology including Netlify CMS, Hugo, Markdown, and React, while building CMS and the website&amp;rsquo;s preview.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reflection-and-next-steps"&gt;Reflection and Next Steps&lt;/h2&gt;
&lt;p&gt;Although the CMS application&amp;rsquo;s basic infrastructure is working and provides a content management interface for updating the webinars and events pages, there are more things I want to improve. During the last meeting with the marketing team, we discussed creating a &lt;a href="https://docs.netlify.com/"&gt;custom widget&lt;/a&gt; for shortcodes and image storage system. I created the necessary GitHub issues and added them to a GitHub project but didn&amp;rsquo;t have the time to implement it.&lt;/p&gt;
&lt;p&gt;I realized I should have had a clearer time schedule of development when writing the proposal and coming up with a priority list of the features I wanted to develop initially. During my meeting with the marketing team in the beginning we only discussed the potential improvement but failed to count the time it takes to develop each feature and the priority of them. If I could communicate about that better and write a better-timed plan, I would be able to implement more new features.&lt;/p&gt;
&lt;p&gt;Also, my mentor and manager taught me to dig deeper into the problem to understand the issue better. It also helped me organize my time better when looking into issues.&lt;/p&gt;
&lt;p&gt;In general, these lessons and experience will benefit me a lot, especially after I enter the industry after graduation in Spring 2021. I feel more prepared now. I have been fascinated by the concept of cloud and cloud infrastructure as code. I feel the potential of cloud technology and believe I will develop my career goal in this direction.&lt;/p&gt;
&lt;p&gt;Soon I will return to my senior year&amp;rsquo;s schoolwork. However, please feel free to keep in touch with me via my &lt;a href="https://www.linkedin.com/in/zephyr-zhou-a17741196/"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="special-thanks"&gt;Special Thanks!&lt;/h2&gt;
&lt;p&gt;First of all, I offer my sincere appreciation to Pulumi leaders, Joe Duffy and Luke Hoban, for offering this internship opportunity despite their busy schedules in the middle of our internship.&lt;/p&gt;
&lt;p&gt;Words can&amp;rsquo;t express my thanks to Praneet Loke, my mentor, who spent every day having sync meetings with me to guide my internship pathway and help me move forward, step by step. I can&amp;rsquo;t count how many times he saved me from daunting problems and patiently explained obscure knowledge.&lt;/p&gt;
&lt;p&gt;I cannot express enough thanks to Lee Zen, our manager, for organizing this internship, ensuring our internship experience, entrusting me with the exciting CMS project, and guiding me towards the correct path during our weekly meeting.&lt;/p&gt;
&lt;p&gt;Moreover, my completion of the internship could not have been accomplished without:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Chris Smith. Thank you for helping me to understand the concept of assuming a role and setting up the credentials and domains for my CMS project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sophia Parafina. Thank you for proofreading my three blog posts and carefully fixing my expression errors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Isaac Harris, Lindsay Marolich, and Jay Wampold. Thank you for spending time learning and trying out the CMS and sharing suggestions for improvement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Zack Chase. Thank you for informing me about the components of Pulumi&amp;rsquo;s website and trying out my CMS application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Freddy Hernandez. Thank you for ensuring our compensation and organizing various team building games, which made my life in quarantine fascinating.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Everyone at Pulumi. Thank you all for helping my fellow interns and me out and contributing to my wonderful internship experience!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description><author>Zephyr Zhou</author><category>pulumi-interns</category></item><item><title>Reflections of a Pulumi Intern</title><link>https://www.pulumi.com/blog/reflections-of-a-pulumi-intern/</link><pubDate>Fri, 18 Sep 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/reflections-of-a-pulumi-intern/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/reflections-of-a-pulumi-intern/index.png" /&gt;
&lt;p&gt;Hi everyone! I&amp;rsquo;m Albert, a soon-to-be sophomore studying computer science at the University of Washington. Today marks my last day as a Pulumi intern, so I figure I&amp;rsquo;d reflect on my experiences up until this point.&lt;/p&gt;
&lt;h2 id="joining-pulumi"&gt;Joining Pulumi&lt;/h2&gt;
&lt;p&gt;I heard of Pulumi for the first time when they visited my school&amp;rsquo;s career fair in January. As I rounded the corner into the &lt;a href="https://www.cs.washington.edu/building"&gt;CSE1 atrium&lt;/a&gt;, I saw a banner titled &amp;ldquo;Modern Infrastructure as Code,&amp;rdquo; with some lines of TypeScript of what appeared to be the creation of an S3 bucket. I found it interesting because it looked so simple and modular. In contrast, when I had played around with AWS in the past to deploy the occasional Django web app, it had always involved following a series of exact instructions (usually go to this dashboard, copy this YAML file, run this command, and pray it works).&lt;/p&gt;
&lt;p&gt;I walked up to the banner&amp;rsquo;s adjacent booth and chatted with &lt;a href="https://www.pulumi.com/blog/author/sean-holung/"&gt;Sean&lt;/a&gt;, a software engineer at Pulumi. He explained how Pulumi was building an open-source platform that allows developers to manage cloud infrastructure using familiar programming languages. To be honest, I didn&amp;rsquo;t have too much experience with the cloud, but I did sympathize with the pain of wrangling with YAML files. The concept sounded compelling, so I told him I was interested in interning there. He gave me the Pulumi recruiter&amp;rsquo;s email, who I later emailed that day with my resume and a brief bit about my background. After a few email and phone exchanges, I came over to the Pulumi office for an in-person interview (which was unfortunately also the only time I ever saw it, due to &lt;a href="https://www.pulumi.com/blog/coronavirus-plan/"&gt;COVID-19&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A couple of weeks later the recruiter called me and extended an offer for the summer intern role! I was incredibly excited about the opportunity to work at such an interesting startup, and especially one working with the cloud, an industry that seemingly dominates my hometown of Seattle. I accepted it a few weeks later since I believed Pulumi had the most fascinating technical challenges to work on relative to the other companies I applied to. From then until summer, I was nervous that my position would be canceled since the coronavirus was forcing many companies to reconsider their budgets. Thankfully Pulumi confirmed that it would shift to a virtual setting, and I started in late June.&lt;/p&gt;
&lt;h2 id="the-first-week"&gt;The First Week&lt;/h2&gt;
&lt;p&gt;I had very little idea of what the internship would look like. In addition to it being virtual, it was my first software engineering gig, so I had no prior experience to base it off. I wasn&amp;rsquo;t sure what my role would be—would I just be assigned a single project and be told to work on it? Would I have a mentor? How does the process of submitting code look like? Fortunately, these questions were answered fairly quickly.&lt;/p&gt;
&lt;p&gt;For the first week, the other interns and I converted Pulumi &lt;a href="https://github.com/pulumi/examples/"&gt;examples&lt;/a&gt; from one language to another. TypeScript seemed to be the most common language, so I converted a few from that language to some of the relatively less popular languages, such as Python and Go. I thought that this was an excellent way to help us interns ramp up since it allowed us to get some baseline experience with Pulumi and the various cloud providers and programming languages it supports. By Friday, I was pretty familiar with how to navigate the various Pulumi repositories and documentation, which was a huge benefit as I launched into my project.&lt;/p&gt;
&lt;h2 id="my-project-crd2pulumi"&gt;My Project: &lt;code&gt;crd2pulumi&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;On the following Monday, I joined a Zoom meeting with &lt;a href="https://www.pulumi.com/blog/author/levi-blackstone/"&gt;Levi&lt;/a&gt; and my mentor &lt;a href="https://www.pulumi.com/blog/author/justin-vanpatten/"&gt;Justin&lt;/a&gt;. They had written up a preliminary design doc on generating SDK types for Kubernetes CustomResources, which would be my project for the summer. I had a minimal background with Kubernetes, so I couldn&amp;rsquo;t fully conceptualize what the end product would look like until a few days later.&lt;/p&gt;
&lt;p&gt;You can define custom fields of a Kubernetes CustomResource using &lt;a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/"&gt;CustomResourceDefinitions&lt;/a&gt; (CRDs). Pulumi already allows you to create CustomResources using the &lt;a href="https://www.pulumi.com/registry/packages/kubernetes/api-docs/apiextensions/"&gt;apiextensions&lt;/a&gt; package. However, there&amp;rsquo;s no way to inherently know the exact fields of a CustomResource, since it&amp;rsquo;s set by some CRD. Therefore we have to set the CustomResource fields to some generic type, such as &lt;code&gt;map[string]interface{}&lt;/code&gt; in Go or &lt;code&gt;pulumi.Input&amp;lt;any&amp;gt;&lt;/code&gt; in TypeScript. This makes filling out the fields for complex CRDs such as cert-manager or Istio very cumbersome since they contain thousands of nested properties. Being able to leverage IDE type-checking and auto-complete makes the process much quicker and less error-prone.&lt;/p&gt;
&lt;p&gt;Throughout the summer, I progressively built &lt;a href="https://github.com/pulumi/crd2pulumi"&gt;&lt;code&gt;crd2pulumi&lt;/code&gt;&lt;/a&gt;, a CLI tool that generates a typed CustomResource from a CRD. I then leveraged this tool to generate libraries for various Kubernetes Operators, which you can find &lt;a href="https://github.com/pulumi/pulumi-kubernetes-crds/"&gt;here&lt;/a&gt;. I still feel like there are additional features to build out in this area though, so I plan to submit a PR here and there even after today.&lt;/p&gt;
&lt;h2 id="school-vs-work"&gt;School vs. Work&lt;/h2&gt;
&lt;p&gt;Before joining Pulumi, all my programming experiences had come from either school projects or practicing coding challenge type problems. So far, these scenarios have been fairly &lt;a href="https://wiki.osdev.org/Atomic_operation"&gt;atomic&lt;/a&gt;, in the sense that they are self-contained and started and finished in a relatively discrete chunk of time. A typical coding project at school is straightforward—I sit down, read the instructions, code everything, and don&amp;rsquo;t think about it until my grade comes back. Most problems (not relating to the difficulty of the course content itself) can usually be resolved by looking more closely at the instructions or consulting the Piazza board.&lt;/p&gt;
&lt;p&gt;In contrast, real software development at Pulumi was far more multi-person, rich, and dynamic. It was challenging, but also far more rewarding. In the first couple of weeks, I was seemingly running into issues at all layers—with the &lt;code&gt;pulumi/pulumi&lt;/code&gt; codegen, with the Go compiler, with the Pulumi CLI, with the Python SDKs, or with my Macbook overheating and crashing whenever I tried opening up the &lt;code&gt;examples&lt;/code&gt; repository in VSCode. Getting stuff to &amp;ldquo;just work&amp;rdquo; often required fixing many nested sub-problems until the root problem could finally be resolved. After a while, I internalized a lot of general debugging heuristics, and developed better skills in squashing bugs and getting code to &amp;ldquo;just work.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I thought that Pulumi gave me an excellent balance between guidance and autonomy. My co-workers gave me an outline of what my project should achieve, and some pointers on how which tools to use, but other than that it was up to me to implement it.&lt;/p&gt;
&lt;p&gt;One aspect that I liked about Pulumi was that its main audience is, of course, developers, so it was easier to design &lt;code&gt;crd2pulumi&lt;/code&gt; since I am a developer. Being able to directly interact with other programmers that use my tool and hear their feedback was immensely satisfying. I loved the energy that came from working with a fast-growing startup that provided real value to real people. It was exciting to come to Monday&amp;rsquo;s team meeting and see Pulumi&amp;rsquo;s user count continuously rise, and hear about the latest deal that the sales team had just closed.&lt;/p&gt;
&lt;h2 id="pros-of-the-virtual-life"&gt;Pros of the Virtual Life&lt;/h2&gt;
&lt;p&gt;I hugely appreciated the flexibility of virtual work-from-home. In conjunction with the two summer classes I was taking, this allowed me to occasionally optimize my schedule. For example, if I had stayed up late on Tuesday night submitting a problem set and I knew I had no meetings tomorrow, I could wake up later on Wednesday morning, but just work a few more hours in the evening to compensate. However, I tried my best to avoid this to keep in sync with the majority of Pulumi employees that are on from 9 am to 5 pm PST.&lt;/p&gt;
&lt;p&gt;After a few days, I settled into a routine of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wake up around 9-10 am and drink some water&lt;/li&gt;
&lt;li&gt;Fire up my Macbook, check Slack and emails, attend meetings if scheduled, read through the reviews to my PR, and write some code&lt;/li&gt;
&lt;li&gt;Eat brunch around 1-2 pm (almost always a double-wrapped Chipotle burrito with brown rice and chicken)&lt;/li&gt;
&lt;li&gt;Write some more code, fix some bugs, push some changes until 5-6 pm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I feel that the quality of the technical practice I received would have been the same, had the internship been in-person. I usually knew which feature or fix to accomplish, and could troubleshoot most technical errors along the way. If I did run into a bug with my code or had questions on how to implement some function, I could always message a co-worker or set up a meeting to resolve it pretty quickly. I also picked up on a lot of knowledge regarding Pulumi, our tech stack, and best practices by just listening in on meetings and browsing the company Slack channel.&lt;/p&gt;
&lt;h2 id="cons-of-the-virtual-life"&gt;Cons of the Virtual Life&lt;/h2&gt;
&lt;p&gt;For me, the largest drawback to work-from-home was diminished social opportunities. Everybody I met at Pulumi was so interesting, talented, and kind, so I&amp;rsquo;m disappointed that I couldn&amp;rsquo;t meet them in person. There&amp;rsquo;s no online replacement for actually seeing a person for 8 hours a day and 5 days a week. I feel that so much of life is disproportionately formed via one-off, chance encounters with people, so not being able to go down to a city such as Seattle and work in an office limited my &lt;a href="https://nevalalee.wordpress.com/2011/10/16/nassim-nicholas-taleb-on-maximizing-serendipity/"&gt;exposure to the envelope of serendipity&lt;/a&gt;. Looking back, I should&amp;rsquo;ve set up more 1-1 meetings with people at Pulumi, just to chat with them and learn from their experiences over lunch.&lt;/p&gt;
&lt;p&gt;Nevertheless, it was still enjoyable, and Pulumi tried its hardest to keep us engaged with remote social activities. For example, &lt;a href="https://www.pulumi.com/blog/author/lee-zen/"&gt;Lee&lt;/a&gt; set up a couple of virtual escape room games which were entertaining.&lt;/p&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;In my view, one of the best lessons I got was that now I know how much I don&amp;rsquo;t know, which is far better than &lt;em&gt;not&lt;/em&gt; knowing how much I don&amp;rsquo;t know. I was exposed to many different areas of tech—Kubernetes, code generation, TypeScript, Go, infrastructure as code, AWS, GCP, and so much more. I&amp;rsquo;ve only begun to scratch the huge surface area of the cloud ecosystem, and I&amp;rsquo;ll always be grateful to the awesome people at Pulumi who helped me get started.&lt;/p&gt;
&lt;p&gt;In two weeks I&amp;rsquo;ll start (also remote) fall quarter at college. If you want to chat, feel free to reach out to me via any of the links on my &lt;a href="https://albertzhong.com/"&gt;website&lt;/a&gt;. Thanks for reading!&lt;/p&gt;</description><author>Albert Zhong</author><category>pulumi-interns</category></item><item><title>The Pulumi Intern Experience</title><link>https://www.pulumi.com/blog/the-pulumi-intern-experience/</link><pubDate>Wed, 16 Sep 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/the-pulumi-intern-experience/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/the-pulumi-intern-experience/index.png" /&gt;
&lt;p&gt;What is the cloud? Three months ago, that one word simply meant a bunch of water suspended in the atmosphere, but now it means more than that.&lt;/p&gt;
&lt;p&gt;Hi, I’m &lt;a href="https://www.linkedin.com/in/sashushankar/"&gt;Sashu Shankar&lt;/a&gt;, a second-year computer science student at the University of Washington, and this is my life as a Pulumi intern!&lt;/p&gt;
&lt;h2 id="my-pulumi-experience"&gt;My Pulumi Experience&lt;/h2&gt;
&lt;h3 id="getting-to-know-the-team"&gt;Getting to Know the Team&lt;/h3&gt;
&lt;p&gt;Let’s be real, onboarding with a new team in a remote situation was tough; the world was quite literally in a state of chaos, and each day was filled with talking to faces on the screen, but everyone was in the same situation, and that made it just a little more bearable. Coming into my first full software engineering internship, I was a nervous wreck, and I had millions of questions. What is the remote culture of the company going to be like? What is their standard for the quality and timeline of work, and am I going to be able to meet them? However, the team was always supportive, and it didn’t take long for me to feel like I was integrated with them and comfortable with the people around me. No matter the time of day, someone was always available to talk!&lt;/p&gt;
&lt;h3 id="asking-questions"&gt;Asking Questions&lt;/h3&gt;
&lt;p&gt;“There is no such thing as a dumb question” was a phrase I heard a lot, but it never fully registered until recently. The “cloud” as we know it is quite vast. Setting it up takes hours, and fully understanding what is going on could take tenfold. Pulumi simplifies the process; however, there is still so much going on even when doing a single thing. This experience truly taught me that there really is no such thing as a dumb question and searching the internet to find answers is an expectation! Nobody knows all the answers, and that is completely okay.&lt;/p&gt;
&lt;h3 id="remote-lifestyle"&gt;Remote Lifestyle&lt;/h3&gt;
&lt;p&gt;I’m definitely not a fan of the &lt;a href="https://www.pulumi.com/blog/coronavirus-plan/"&gt;remote environment&lt;/a&gt;, however, I’m the kind of person that is more productive at night, so it allowed me to shift my work to times when I knew I would get things done. That said, face to face interaction was something I missed a lot, as it’s understandably harder to get to know people over a computer. However, since Pulumi already has many remote engineers, it was a very smooth process to get set up and start working right away.&lt;/p&gt;
&lt;h2 id="the-project-experience"&gt;The Project Experience&lt;/h2&gt;
&lt;h3 id="introduction-to-the-pulumi-model"&gt;Introduction to the Pulumi Model&lt;/h3&gt;
&lt;p&gt;I worked on the Platform team for the last 3 months, and they focused their work on the Pulumi SDK. The first few weeks were a huge learning curve, as the interns were tasked with converting Pulumi deployment examples from Typescript to Python, C#, and Go. This intro project taught me a lot about cloud resources, how they are deployed, and introduced me to helpful debugging tools through this process. I also learned how to write &lt;a href="https://www.pulumi.com/docs/iac/concepts/testing/"&gt;tests&lt;/a&gt; to validate output for a deployment which proved helpful as I learned how the entire process was working.&lt;/p&gt;
&lt;h3 id="kube2pulumi-tooling"&gt;kube2pulumi Tooling&lt;/h3&gt;
&lt;p&gt;I built a CLI tool, and an open-source library to convert Kubernetes YAML manifests to Pulumi in a user-defined language &lt;a href="https://www.pulumi.com/blog/introducing-kube2pulumi"&gt;check out kube2pulumi!&lt;/a&gt;. This was done so that Kubernetes users could easily migrate to Pulumi, and use familiar programming languages to tame YAML&amp;rsquo;s complexity. I truly learned a lot from this experience as it was my first time designing and implementing a project end to end in a set time frame. Utilizing existing open-source libraries, code generation techniques, and compilers theory were just some of the many things I got to delve into.&lt;/p&gt;
&lt;h3 id="ui-interface"&gt;UI Interface&lt;/h3&gt;
&lt;p&gt;Another feature that came out of this was a UI layer to access it directly on the web; this forced me to think about different error scenarios and how they would be handled to make it a polished experience. Additionally, this really exposed the programmatic usage of kube2pulumi when writing the web service. It allowed me to further improve the overall experience in whichever form the user decides to use. To top it all off, going through a feature launch with the team was extremely exciting! It&amp;rsquo;s one thing to consistently work on an internal tool, but it&amp;rsquo;s another ball game when you are shipping your work directly to the community.&lt;/p&gt;
&lt;h2 id="final-thoughts"&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Coming into industry work right out of my freshman year of college was a daunting task; however, I wouldn’t have wanted to intern at any other place other than Pulumi! The mentorship, team camaraderie, and, most importantly, the exposure to new technologies and learning made this the best possible experience I could’ve imagined. I’m super proud of what I could accomplish with the team, and I’m excited to see what the future holds for the company!&lt;/p&gt;
&lt;p&gt;What is the cloud? Three months later, I can say that the cloud, to me, is a vast tool for people to build their visions and dreams, and Pulumi is the place I would come to help me get that started :)&lt;/p&gt;
&lt;h2 id="shoutouts-"&gt;Shoutouts :)&lt;/h2&gt;
&lt;p&gt;Thank you &lt;a href="https://github.com/albert-zhong"&gt;Albert&lt;/a&gt;, &lt;a href="https://github.com/zephyrz73"&gt;Zephyr&lt;/a&gt;, and &lt;a href="https://github.com/jetvova"&gt;Vova&lt;/a&gt; for being incredible, kind, and helpful intern buddies!&lt;/p&gt;
&lt;p&gt;Thank you &lt;a href="https://github.com/evanboyle"&gt;Evan&lt;/a&gt; for being an amazing mentor by being so approachable, and always being there everyday. You were always so patient with me and answered virtually any question I threw at you :)&lt;/p&gt;
&lt;p&gt;Thank you &lt;a href="https://github.com/leezen"&gt;Lee&lt;/a&gt; and and &lt;a href="https://github.com/lukehoban"&gt;Luke&lt;/a&gt; for being such organized, motivating, and empathetic managers!&lt;/p&gt;
&lt;p&gt;Thank you to &lt;a href="https://github.com/lblackstone"&gt;Levi&lt;/a&gt;, &lt;a href="https://github.com/jaxxstorm"&gt;Lee Briggs&lt;/a&gt;, &lt;a href="https://github.com/komalali"&gt;Komal&lt;/a&gt;, &lt;a href="https://github.com/pgavlin"&gt;Pat&lt;/a&gt;, and &lt;a href="https://github.com/MikhailShilkov"&gt;Mikhail&lt;/a&gt; for being so open and friendly and always being available and sharing your experience when I needed anything at all!&lt;/p&gt;
&lt;p&gt;And finally, thank you to everyone at Pulumi and the whole platform team for giving me this opportunity!&lt;/p&gt;</description><author>Sashu Shankar</author><category>pulumi-interns</category></item><item><title>Supporting Kubernetes with Faster, Easier Test Environments</title><link>https://www.pulumi.com/blog/supporting-kubernetes-with-pulumi/</link><pubDate>Thu, 30 Apr 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/supporting-kubernetes-with-pulumi/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/supporting-kubernetes-with-pulumi/index.png" /&gt;
&lt;p&gt;Scott Lowe is a 20+ year veteran of the IT industry and a Staff Kubernetes Architect at VMWare. He’s a prolific author (seven books) and &lt;a href="https://blog.scottlowe.org"&gt;blogger&lt;/a&gt;. His technology-focused blog covers a range of topics that include cloud computing (AWS, Azure, and Kubernetes), virtualization (KVM, VMware vSphere), open-source tools (Terraform, Ansible, Vagrant, and others), and networking (Open vSwitch, Linux networking).&lt;/p&gt;
&lt;p&gt;For this guest post, Scott demonstrates how he uses Pulumi to deploy AWS test environments across multiple regions to help with testing various Kubernetes tools and projects, including the &lt;a href="https://github.com/kubernetes-sigs/cluster-api"&gt;Cluster API project&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="cluster-api"&gt;Cluster API&lt;/h2&gt;
&lt;p&gt;The Cluster API project is a Kubernetes project for implementing a declarative API to manage the lifecycle of a Kubernetes cluster from creation, configuration, and maintenance. The project lives outside of the Kubernetes core project but follows best practices for using a declarative API. Ultimately, it seeks to define everyday operations, provide a default implementation, and the ability to swap between implementations seamlessly.&lt;/p&gt;
&lt;p&gt;Cluster API allows you to define Kubernetes clusters as a Kubernetes resource. It lets you use the Kubernetes API to manage Kubernetes clusters, which sounds a little bit like inception, but it greatly simplifies lifecycle management both on-prem and in the cloud.&lt;/p&gt;
&lt;h2 id="benefits-of-infrastructure-as-code"&gt;Benefits of Infrastructure as Code&lt;/h2&gt;
&lt;p&gt;Pulumi is well suited for enabling me to help test projects like Cluster API. I&amp;rsquo;m not a developer (not yet), but by helping to test projects like Cluster API as they are developed, I can provide useful feedback. Pulumi makes it possible to define, test quickly, and deploy infrastructure components, whether those components are used to test new builds, verify functionality, assist with capturing information in documentation, or something else entirely.&lt;/p&gt;
&lt;h2 id="infrastructure-as-code-in-practice"&gt;Infrastructure as Code in Practice&lt;/h2&gt;
&lt;p&gt;To help with testing parts of Cluster API&amp;rsquo;s functionality, as well as to help with testing other configurations or tools related to Kubernetes, Pulumi helps manage my test environment or sandbox. In this instance, I&amp;rsquo;m using a Pulumi project written in TypeScript. This Pulumi project manages a consistent configuration across four AWS regions worldwide. This is set up as a single Pulumi project with four stacks; each stack defines infrastructure for a different AWS region worldwide.&lt;/p&gt;
&lt;p&gt;All the TypeScript code is parameterized, so all you have to do is change the stack and then spin it up in your desired region. It looks for resources in that region like the right AMIs, etc. Right now, the code only accommodates four specific regions, but adding new regions would be pretty trivial.&lt;/p&gt;
&lt;p&gt;It then spins up a VPC with both private and public subnets, attaches an internet gateway, creates security groups for various hosts, and creates one instance for an SSH bastion host that only allows SSH traffic into the cluster. This bastion host serves as the gateway by which you reach everything else inside the VPC.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/supporting-kubernetes-with-pulumi/scott_lowe_1.png" alt="VPCs"&gt;&lt;/p&gt;
&lt;p&gt;Maps provide different configuration values for each region, such as different IP address values per region and different &amp;ldquo;friendly names&amp;rdquo; for each region.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/supporting-kubernetes-with-pulumi/scott_lowe_2.png" alt="Configuration Values"&gt;&lt;/p&gt;
&lt;p&gt;A second Pulumi project, again with four stacks, is used to spin up AWS EC2 instances, which are used as Cluster API management clusters. This second project creates instances inside the infrastructure that was spun up by the first project. A stack reference is used to refer to a stack in the first project; this connection is what enables the second project to place its resources inside the infrastructure created by the first project.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/supporting-kubernetes-with-pulumi/scott_lowe_3.png" alt="Cluster API"&gt;&lt;/p&gt;
&lt;p&gt;Once there are a couple of instances running in the region, native Kubernetes tools bootstrap the initial Kubernetes cluster for that region. This first Kubernetes cluster becomes the management cluster, and from there, it&amp;rsquo;s possible to create additional Kubernetes clusters as needed using Cluster API.&lt;/p&gt;
&lt;p&gt;Aside from helping create clusters in multiple regions, Pulumi makes it easy to spin up other, independent new environments for testing. A third Pulumi project creates a VPC with all the necessary added components (subnets, route tables, route table associations, NAT gateways, and an Internet gateway) for testing other Kubernetes-related technologies or projects. Because this environment is ephemeral, it isn&amp;rsquo;t parameterized for multiple regions and is typically used only within a single AWS region.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not a complex environment: you create the base AWS infrastructure then add Pulumi stack references to build on top of that infrastructure to add additional instances. That enables you to spin up instances inside those environments as needed, and then tear them down when testing completes.&lt;/p&gt;
&lt;p&gt;For example, I recently needed to refresh my AWS lab infrastructure. There were a variety of reasons, but in the end, I had a set of changes I needed to apply to all four regions where my Pulumi project maintains infrastructure. After making the necessary changes to the TypeScript code, I was able to tear down all my lab infrastructure and re-create it in a matter of 10 to 15 minutes with a simple &lt;code&gt;pulumi destroy&lt;/code&gt; followed by &lt;code&gt;pulumi up&lt;/code&gt;. Making these changes without an infrastructure-as-code tool like Pulumi would have taken a lot longer.&lt;/p&gt;
&lt;p&gt;You can watch Scott demonstrate his testing environment.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/EWILzQ7_jMI?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id="your-infrastructure-as-code-story"&gt;Your Infrastructure as Code Story&lt;/h2&gt;
&lt;p&gt;We appreciate Scott taking the time to share his infrastructure as code story. Let us know you’re using Pulumi on &lt;a href="https://twitter.com/pulumicorp"&gt;Twitter&lt;/a&gt; or on &lt;a href="https://slack.pulumi.com/"&gt;Slack&lt;/a&gt;.&lt;/p&gt;</description><author>Scott Lowe</author><category>kubernetes</category></item><item><title>Life of a Pulumi Intern</title><link>https://www.pulumi.com/blog/life-of-a-pulumi-intern/</link><pubDate>Thu, 02 Apr 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/life-of-a-pulumi-intern/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/life-of-a-pulumi-intern/index.png" /&gt;
&lt;p&gt;👋I&amp;rsquo;m Tasia, a Computer Science student at the University of Washington and Pulumi&amp;rsquo;s very first intern. Read on to learn about some of my thoughts and experiences from these past few months!&lt;/p&gt;
&lt;h2 id="why-pulumi"&gt;Why Pulumi?&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve interned at a few different companies before, but for my last internship, there were several things I was looking for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A start-up. All the companies I worked at previously had at least a couple thousand people, and I wanted to see first-hand the difference in both engineering and culture between larger, more established companies and smaller, newer ones.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A knowledgeable engineering team. Although I knew I wanted to work at a start-up, I also wanted access to the knowledge and expertise that usually comes with more senior engineers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A product I can get behind. There&amp;rsquo;s a lot of start-ups out there, and not all of them work on things that I think are viable or exciting. Working on something that I can see myself and others using makes getting up for work a little more bearable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Competitive compensation. Even though I don&amp;rsquo;t expect smaller companies to be as financially well-off as the other companies I worked for, I still wanted to be paid comparably.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Opportunities to learn something new. The main goal for &lt;em&gt;all&lt;/em&gt; of my internships was basically just to learn something new. I don&amp;rsquo;t really know what I want to do for the rest of my career, but the best way I think to figure that out is to try a bit of everything!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you haven&amp;rsquo;t guessed already, Pulumi checks all of these boxes! Although Pulumi was only founded a few years ago, their team is rich with experienced engineers and their product has taken a foothold in companies all over the world. Especially with the release of 2.0 right around the corner, I&amp;rsquo;m glad I joined at such an exciting time.&lt;/p&gt;
&lt;h2 id="working-across-the-company"&gt;Working Across the Company&lt;/h2&gt;
&lt;p&gt;Pulumi engineering is currently split up into two teams: the &lt;em&gt;Service&lt;/em&gt; Team and the &lt;em&gt;Platform&lt;/em&gt; Team. The service team primarily works on the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/"&gt;Pulumi Service&lt;/a&gt;, whereas the platform team primarily works on the &lt;a href="https://www.pulumi.com/product/#sdk"&gt;Pulumi SDK&lt;/a&gt;. Although I&amp;rsquo;m technically a part of the Service Team, one of the benefits of working as an intern in a small company is the flexibility to work on projects across the whole company.&lt;/p&gt;
&lt;p&gt;Within the Service Team, I added &lt;a href="https://www.pulumi.com/blog/pulumi-service-improvements_02-2020/#first-class-support-for-tags"&gt;support for tags&lt;/a&gt; within the Pulumi Service and created new pages to &lt;a href="https://www.pulumi.com/blog/pulumi-service-improvements_02-2020/#reverse-stack-permissions-view"&gt;view a member&amp;rsquo;s specific stack permissions&lt;/a&gt;. Within the Platform Team, I added support for both &lt;a href="https://www.pulumi.com/docs/concepts/resources#transformations"&gt;transformations&lt;/a&gt; and &lt;a href="https://github.com/pulumi/pulumi-docker"&gt;Docker images&lt;/a&gt; in Go. Lastly, in a cross-team effort, I&amp;rsquo;ve been helping out with updating our &lt;a href="https://github.com/pulumi/pulumi-terraform-bridge"&gt;code generation tools&lt;/a&gt; for Pulumi 2.0. I&amp;rsquo;m sparing the nitty gritty details here for the sake of time and space, but most of the repos I worked in are open-source, so feel free to &lt;a href="https://github.com/pulumi"&gt;check them out&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Simply put, I took on the work of a full-time engineer, only with slightly more flexibility and a lot less experience. Prior to working at Pulumi, I had basically zero knowledge on Angular, cloud providers, and code generation. Now, I&amp;rsquo;m still nowhere near an expert on any of these, but I feel like I have a stronger grasp on where the software engineering industry is headed, thanks to the support of everyone I worked with!&lt;/p&gt;
&lt;h2 id="things-ive-learned"&gt;Things I&amp;rsquo;ve Learned&lt;/h2&gt;
&lt;p&gt;Earlier I mentioned that one of my main goals for any internship is to learn. Here are just three key things I&amp;rsquo;ve learned about myself and software engineering during this one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Remote life is not the life for me. Due to &lt;a href="https://www.pulumi.com/blog/coronavirus-plan/"&gt;unforeseen circumstances&lt;/a&gt;, I spent the last month of my internship in my apartment. I always thought I was a bit of a homebody, but it turns out that staying in one place for more than one day makes me stir crazy, and I&amp;rsquo;m nowhere near as productive in my room as I think I am. On the upside, Pulumi already had several remote engineers, so all the infrastructure was already in place to continue the actual work side of things fairly smoothly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Writing tests before writing code is actually a good strategy. I remember learning this in one of my classes and thinking &amp;ldquo;Yeah that seems like a good idea, but what person would actually do that?&amp;rdquo;. Apparently, that person would be me. Often times, I would find myself starting to code something without really understanding possible use cases. Making myself write tests beforehand clears that up pretty quickly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using &amp;ldquo;the cloud&amp;rdquo; is anything but simple. To be completely fair, I already knew this. My previous experience with cloud providers involved reading through multi-page documents just to set everything up, and clicking a handful of buttons on the console without really understanding why. Pulumi hugely streamlines that process, but even still there&amp;rsquo;s so much that goes into doing a single thing on a cloud. In other words, I have a newfound appreciation for people working on cloud infrastructure and I feel lucky to be entering the industry when resources like Pulumi already exist.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="final-thoughts"&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Overall, my time at Pulumi wasn&amp;rsquo;t quite the chaotic startup experience I was expecting. I came into Pulumi with this idea that start-ups consisted of stressed-out people, working around the clock, and disorganization across the board. My time here at Pulumi, however, was anything but. Looking back, the only major differences I felt while working at Pulumi (both engineering-related and otherwise) compared to my previous companies were the lack of free meals (which as a college student, I&amp;rsquo;m very partial to) and intern events (which as the only intern, I didn&amp;rsquo;t expect any of), which I think really speaks to the maturity of their engineering and leadership teams. I&amp;rsquo;m proud seeing what I&amp;rsquo;ve accomplished, and excited to see the future of Pulumi!&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m soon returning to (virtual) classes (thanks, coronavirus!), but feel free to reach out to me via &lt;a href="https://www.linkedin.com/in/anastasiahalim/"&gt;LinkedIn&lt;/a&gt; to learn more about me and/or my experiences!&lt;/p&gt;</description><author>Tasia Halim</author><category>pulumi-interns</category></item><item><title>Refactoring Pulumi Code with `aliases`</title><link>https://www.pulumi.com/blog/cumundi-guest-post/</link><pubDate>Thu, 26 Mar 2020 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/cumundi-guest-post/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/cumundi-guest-post/index.png" /&gt;
&lt;p&gt;&lt;strong&gt;Guest Article:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/ringodesmet/"&gt;Ringo De Smet&lt;/a&gt;, Founder of Cumundi, standardizes on Pulumi for writing infrastructure as reusable code libraries for his customers. Pulumi enables him to rapidly iterate through the build-test-release cycle of these building blocks.&lt;/p&gt;
&lt;p&gt;Cumundi helps companies adopt cloud infrastructure in a more integral way. It has found that 75% of companies’ needs are covered by ‘vanilla’ infrastructure patterns. However, due to a shortage of people and time, there has been limited investment to take full advantage of cloud-native configurations - which can lead to inefficiency, poor performance, and higher costs.&lt;/p&gt;
&lt;h2 id="how-pulumi-code-keeps-up-with-changing-requirements"&gt;How Pulumi Code Keeps Up with Changing Requirements&lt;/h2&gt;
&lt;p&gt;At Cumundi, we build reusable libraries for our customers to set up their infrastructure while following best practices. These best practices include a range of &amp;ldquo;non-functional requirements&amp;rdquo; - infrastructure patterns - which often receive less focus than application features. Where feasible, Cumundi encapsulates these non-functional requirements into infrastructure code libraries. This enables Cumundi to serve clients using all major clouds while keeping application-focused infrastructure libraries clean and modular.&lt;/p&gt;
&lt;p&gt;It may come as no surprise that we also use Pulumi to manage Cumundi&amp;rsquo;s own infrastructure. As a young company (founded January 1st!), it is hard to foresee how our infrastructure needs will evolve. With Pulumi, we write code in a modern programming language, and, good coding practice is not to &lt;a href="http://wiki.c2.com/?PrematureOptimization"&gt;optimize prematurely&lt;/a&gt; because the future is unpredictable. Another coding best practice is &lt;a href="https://en.wikipedia.org/wiki/Test-driven_development"&gt;red-green-refactor&lt;/a&gt; or formally known as Test-Driven Development. You take the current code, write a test for the new requirement, which initially fails (red). Next, you implement the code in the most straightforward way to make the test succeed (green) and you complete the cycle by refactoring the code to keep the design in proper shape.&lt;/p&gt;
&lt;p&gt;This blog post demonstrates a TDD cycle for Pulumi code with a reduced version of the code used to configure the internal infrastructure we provide for each customer. This example focuses on one specific Pulumi resource property: &lt;a href="https://www.pulumi.com/docs/concepts/resources#aliases"&gt;&lt;code&gt;aliases&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All the code is &lt;a href="https://github.com/cumundi/pulumi-refactoring-aliases"&gt;available on Github&lt;/a&gt; if you want to follow along with a full project setup. Every step described here is committed as a separate branch with the starting point on &lt;code&gt;master&lt;/code&gt;, the default branch.&lt;/p&gt;
&lt;h3 id="the-starting-point"&gt;The Starting Point&lt;/h3&gt;
&lt;p&gt;Every Pulumi project starts empty, so ours is no exception. This is how our main Pulumi code file looks for now.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gitlab&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Applying the above code does nothing, which you can see in the &lt;em&gt;Resources&lt;/em&gt; tab on the hosted Pulumi platform:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/cumundi-guest-post/start.png" alt="Starting point"&gt;&lt;/p&gt;
&lt;h3 id="adding-the-git-repository"&gt;Adding the Git Repository&lt;/h3&gt;
&lt;p&gt;We create a separate repository for each of our customers:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;gitlab&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gitlabNamespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;namespace&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstCustomer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FirstCustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;first-customer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;First Customer code&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;namespaceId&lt;/span&gt;: &lt;span class="kt"&gt;gitlabNamespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;visibilityLevel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;private&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;defaultBranch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;master&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pipelinesEnabled&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;issuesEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;wikiEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;snippetsEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;containerRegistryEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mergeRequestsEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mergeMethod&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;onlyAllowMergeIfPipelineSucceeds&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sharedRunnersEnabled&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We wrote the code in the simplest way to get the job done. After &lt;code&gt;pulumi up&lt;/code&gt;, the Gitlab project is created:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/cumundi-guest-post/step1.png" alt="Step 1"&gt;&lt;/p&gt;
&lt;h3 id="a-customer-needs-cloud-infrastructure"&gt;A Customer Needs Cloud Infrastructure&lt;/h3&gt;
&lt;p&gt;For our second customer, I just duplicated the creation of the Gitlab repository and created a Google Cloud project and service account.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secondCustomer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SecondCustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;// properties here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secondCustomerProject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;organizations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SecondCustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;second-customer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Second Customer Infrastructure&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceAccountSecondCustomer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ServiceAccountSecondCustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;accountId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;secondcustomer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Service Account for Second Customer project&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;project&lt;/span&gt;: &lt;span class="kt"&gt;secondCustomerProject.projectId&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceAccountSecondCustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ServiceAccountSecondCustomerKey&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;serviceAccountId&lt;/span&gt;: &lt;span class="kt"&gt;serviceAccountSecondCustomer.email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secondCustomerGitlabCIVariable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ProjectVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SecondCustomerGCPAccess&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;project&lt;/span&gt;: &lt;span class="kt"&gt;secondCustomer.id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;variableType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;GOOGLE_APPLICATION_CREDENTIALS&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;value&lt;/span&gt;: &lt;span class="kt"&gt;serviceAccountSecondCustomerKey.privateKey.apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;protected&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;environmentScope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These resources are all added with the &lt;code&gt;Stack&lt;/code&gt; as their parent in the resource view, as seen below. This is getting clumsy.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/cumundi-guest-post/step2.png" alt="Step 2"&gt;&lt;/p&gt;
&lt;p&gt;Visualization goes a long way, but a flat list of resources does not clearly show what belongs together.&lt;/p&gt;
&lt;h3 id="find-relationships-between-resources"&gt;Find Relationships between Resources&lt;/h3&gt;
&lt;p&gt;In the current state of the code, we created a Google Cloud service account and a key. Since a key can&amp;rsquo;t be created without a service account, we also created a Gitlab CI project variable for the Gitlab project of the second customer. Two cases of a parent-child relationship.&lt;/p&gt;
&lt;p&gt;Although we have this relationship between our resources, the Pulumi state graph doesn&amp;rsquo;t display it. How can we change this without affecting the real resources on Gitlab and Google Cloud?&lt;/p&gt;
&lt;p&gt;We can pass &lt;a href="https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/pulumi/#CustomResourceOptions"&gt;&lt;code&gt;CustomResourceOptions&lt;/code&gt;&lt;/a&gt; as the last argument to every Pulumi resource that we want to create and use &lt;code&gt;parent&lt;/code&gt; and &lt;code&gt;aliases&lt;/code&gt; for refactoring.&lt;/p&gt;
&lt;p&gt;To link the key to the service account, we set the &lt;code&gt;parent&lt;/code&gt; property to the service account resource. If you run &lt;code&gt;pulumi preview&lt;/code&gt;, Pulumi wants to recreate the key. It wants to do this because it searches for the key as a child resource of the service account. In your last applied Pulumi state, that is not the case.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceAccountSecondCustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ServiceAccountSecondCustomerKey&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;serviceAccountId&lt;/span&gt;: &lt;span class="kt"&gt;serviceAccountSecondCustomer.email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;: &lt;span class="kt"&gt;serviceAccountSecondCustomer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;How can we tell Pulumi that the existing key resource fulfills the expectation in our code? The &lt;code&gt;aliases&lt;/code&gt; property comes to the rescue!&lt;/p&gt;
&lt;p&gt;If you want to rename resources in a Pulumi state or change the parent-child relationships, then the &lt;code&gt;aliases&lt;/code&gt; property is your friend. Let&amp;rsquo;s indicate in our code that the existing key resource, linked to the &lt;code&gt;Stack&lt;/code&gt;, is the key of interest.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceAccountSecondCustomerKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ServiceAccountSecondCustomerKey&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;serviceAccountId&lt;/span&gt;: &lt;span class="kt"&gt;serviceAccountSecondCustomer.email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;: &lt;span class="kt"&gt;serviceAccountSecondCustomer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;aliases&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.rootStackResource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Before going forward, we also changed the relationship between the Gitlab repository and the Gitlab CI variable. When you run &lt;code&gt;pulumi up&lt;/code&gt;, nothing changes on Gitlab and Google Cloud. But after applying the changes, refreshing the resource view on the Pulumi platform displays the following state graph.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/cumundi-guest-post/step3.png" alt="Step 3"&gt;&lt;/p&gt;
&lt;h3 id="clean-up-duplication"&gt;Clean Up Duplication&lt;/h3&gt;
&lt;p&gt;In the previous step, I copied the code for the Gitlab repository from our first customer to our second customer. In this step, we resolve the duplication issue, and ensure that customer projects can conditionally create the Google infrastructure needed.&lt;/p&gt;
&lt;p&gt;I introduced a &lt;code&gt;ComponentResource&lt;/code&gt; subclass, which encapsulates moving the code for the individual resources into the customer resource class. As we set up Google Cloud resources for other customers, we create a Google Cloud project and related resources only when required. We can use a regular Typescript &lt;code&gt;if&lt;/code&gt; conditional for this.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;gcp&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/gcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;gitlab&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/gitlab&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;util&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;util&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ProjectArgs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// The name of the customer, e.g. &amp;#34;First Customer&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.Input&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Indication whether we need to create Google Cloud infrastructure for this customer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;needsGoogleInfra&lt;/span&gt;: &lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Namespace in Gitlab to create the repositories in.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gitlabNamespace?&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.Input&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Pulumi custom resource representing a customer project
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentResource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;: &lt;span class="kt"&gt;ProjectArgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.CustomResourceOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;customer:Project&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/([a-zA-Z])(?=[A-Z])/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;$1-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;serviceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/([a-zA-Z])(?=[A-Z])/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;$1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gitlabProject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;description&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.interpolate&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; code`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;namespaceId&lt;/span&gt;: &lt;span class="kt"&gt;args.gitlabNamespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;visibilityLevel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;private&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;defaultBranch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;master&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pipelinesEnabled&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;issuesEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;wikiEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;snippetsEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;containerRegistryEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mergeRequestsEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mergeMethod&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;onlyAllowMergeIfPipelineSucceeds&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sharedRunnersEnabled&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;needsGoogleInfra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;// Google Cloud and Gitlab CI Variable code here.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that I have our custom resource, I can use it for our existing customers. Our refactored main Pulumi file looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstCustomer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FirstCustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;First Customer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;needsGoogleInfra&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gitlabNamespace&lt;/span&gt;: &lt;span class="kt"&gt;gitlabNamespace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secondCustomerProject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;SecondCustomer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Second Customer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;needsGoogleInfra&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;gitlabNamespace&lt;/span&gt;: &lt;span class="kt"&gt;gitlabNamespace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we apply this to our infrastructure, two custom resources are created and saved to your Pulumi state.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/cumundi-guest-post/step4.png" alt="Step 4"&gt;&lt;/p&gt;
&lt;p&gt;However, we have not updated the parent-child relationships.&lt;/p&gt;
&lt;h3 id="fix-the-remaining-relationships"&gt;Fix the Remaining Relationships&lt;/h3&gt;
&lt;p&gt;We have a representation of a customer project in our Pulumi state graph, but we want to see the resources of each customer as child resources of this abstraction, right?&lt;/p&gt;
&lt;p&gt;The same trick with &lt;code&gt;parent&lt;/code&gt; and &lt;code&gt;aliases&lt;/code&gt; is used to &lt;em&gt;re-parent&lt;/em&gt; our resources. Our resources are created within the constructor of our &lt;code&gt;Project&lt;/code&gt; class. In Typescript, the language used in this example, we can use the keyword &lt;code&gt;this&lt;/code&gt; to point to the &lt;code&gt;Project&lt;/code&gt; instance.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentResource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;: &lt;span class="kt"&gt;ProjectArgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.CustomResourceOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;customer:Project&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/([a-zA-Z])(?=[A-Z])/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;$1-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;serviceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/([a-zA-Z])(?=[A-Z])/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;$1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gitlabProject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;gitlab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;: &lt;span class="kt"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;description&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.interpolate&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; code`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;namespaceId&lt;/span&gt;: &lt;span class="kt"&gt;args.gitlabNamespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;visibilityLevel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;private&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;defaultBranch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;master&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pipelinesEnabled&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;issuesEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;wikiEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;snippetsEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;containerRegistryEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mergeRequestsEnabled&lt;/span&gt;: &lt;span class="kt"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;mergeMethod&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;onlyAllowMergeIfPipelineSucceeds&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sharedRunnersEnabled&lt;/span&gt;: &lt;span class="kt"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;: &lt;span class="kt"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;aliases&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;: &lt;span class="kt"&gt;pulumi.rootStackResource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;While we are changing parent-child relationships, the service account resource is also updated to have the Google Cloud project as its parent. The result should look like the state graph below.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/cumundi-guest-post/step5.png" alt="Step 5"&gt;&lt;/p&gt;
&lt;p&gt;If another developer reads this code, they might not immediately have a clear picture of how everything is wired together. However, looking at the Pulumi resource visualization, the following properties can immediately be deduced:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;our infrastructure has 2 customer projects&lt;/li&gt;
&lt;li&gt;one customer only has a Gitlab repository, while the other also has Google Cloud infrastructure&lt;/li&gt;
&lt;li&gt;if we create a Google Cloud project, we create a service account and a key together with it&lt;/li&gt;
&lt;li&gt;if we create a Google Cloud project, we also set a Gitlab CI variable. It&amp;rsquo;s a pity though I can&amp;rsquo;t link the Gitlab CI variable to the key.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="next-steps"&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;You probably noticed by now that the &lt;code&gt;aliases&lt;/code&gt; property accepts a list. You can provide entries like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{ name: &amp;lt;some old name&amp;gt; }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{ parent: &amp;lt;some previous parent&amp;gt; }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{ name: &amp;lt;some old name&amp;gt;, parent: &amp;lt;some previous parent&amp;gt; }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that putting the first two in the &lt;code&gt;aliases&lt;/code&gt; list is not the same as putting the third one as the single entry. I leave it up to the reader to test it and understand the difference.&lt;/p&gt;
&lt;p&gt;The take away from this example is: values for &lt;code&gt;name&lt;/code&gt; in the &lt;code&gt;aliases&lt;/code&gt; property can not be &lt;code&gt;Input&lt;/code&gt;s as they need to be resolvable at &lt;code&gt;preview&lt;/code&gt; time, similar to the name of the resources themselves.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The Pulumi programming model well designed with regards to the evolution of an infrastructure. With &lt;code&gt;ComponentResource&lt;/code&gt; and the &lt;code&gt;parent&lt;/code&gt; and &lt;code&gt;aliases&lt;/code&gt; properties, refactoring your infrastructure code is a breeze with visualizing abstractions on the Pulumi platform.&lt;/p&gt;</description><author>Ringo De Smet</author><category>aliases</category><category>refactoring</category></item><item><title>Pulumi Sweeps into KubeCon</title><link>https://www.pulumi.com/blog/kubecon-review/</link><pubDate>Mon, 25 Nov 2019 14:03:19 -0600</pubDate><guid>https://www.pulumi.com/blog/kubecon-review/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/kubecon-review/index.png" /&gt;
&lt;p&gt;&lt;img src="booth.jpg" alt="Pulumi Booth KubeCon2019"&gt;&lt;/p&gt;
&lt;p&gt;We had a fantastic time at KubeCon in San Diego. At the event, the Pulumi team released two technology previews: &lt;a href="https://www.pulumi.com/docs/iac/clouds/kubernetes/guides/"&gt;Pulumi Crosswalk for Kubernetes&lt;/a&gt; and &lt;a href="https://github.com/pulumi/pulumi-query-kubernetes"&gt;Pulumi Query for Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Crosswalk for Kubernetes is a set of common patterns compiled in playbooks. These patterns reduce the complex Kubernetes API syntax by providing trusted defaults with idiomatic Kubernetes. Checkout a quick introduction to Crosswalk for Kubernetes in this &lt;a href="https://www.pulumi.com/blog/inside-crosswalk-for-kubernetes/"&gt;blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/sarahnovotny"&gt;Sara Novotny&lt;/a&gt; defined observability as &lt;em&gt;“the ability to ask of your system and learn from it”&lt;/em&gt; during her &lt;a href="https://www.youtube.com/watch?v=W_8MHdtrgZE"&gt;keynote&lt;/a&gt; with &lt;a href="https://twitter.com/lizthegrey"&gt;Liz Fong-Jones&lt;/a&gt;. Query for Kubernetes enables observability programmatically by exposing resource processes through either batch or streaming queries. Learn more about Query for Kubernetes in our &lt;a href="https://www.pulumi.com/blog/query-kubernetes/"&gt;blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To see both Crosswalk and Query for Kubernetes in action, watch the demo video!&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/X96EMLi8uJY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Pulumi engineers, &lt;a href="https://twitter.com/eckrengel"&gt;Erin Krengel&lt;/a&gt; and Sean Holung, presented &lt;code&gt;Are You About to Break Prod? Acceptance Testing with Ephemeral Environments&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/uploads/content/blog/kubecon-review/krengel-holung.jpg" alt="Krengel and Holung KubeCon Presentation"&gt;&lt;/p&gt;
&lt;p&gt;Addressing a packed room, they showed how to use ephemeral environments (short lived environments that mimic production) to automate testing. Kudos to the &lt;a href="https://twitter.com/CloudNativeFdn"&gt;CNCF&lt;/a&gt; for making the presentation videos available quickly, you can watch Erin and Sean&amp;rsquo;s presentation on YouTube.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/jAQhDZiRzBQ?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://twitter.com/funcofjoe"&gt;Joe Duffy&lt;/a&gt; sums up our experience below. We hope to see you next year at KubeCon 2020!&lt;/p&gt;</description><author>Sophia Parafina</author><category>kubernetes</category><category>pulumi-events</category></item><item><title>Three Infrastructure as Code Blog Posts You Should Read</title><link>https://www.pulumi.com/blog/pulumi-bloggers-oct-2019/</link><pubDate>Thu, 24 Oct 2019 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumi-bloggers-oct-2019/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-bloggers-oct-2019/index.png" /&gt;
&lt;p&gt;We are always excited when people join the Infrastructure as Code community and write about their experiences. Pulumi can be used for a range of common tasks such as standardizing VPC builds, building VSphere virtual machines, or deploying your infrastructure from a CI/CD pipeline. Whether it&amp;rsquo;s &lt;code&gt;TypeScript&lt;/code&gt;, &lt;code&gt;JavaScript&lt;/code&gt;, or &lt;code&gt;Python&lt;/code&gt; you can build your infrastructure with your language and tools of choice. Here are three new blog posts that show how to use Pulumi with code examples to perform these tasks.&lt;/p&gt;
&lt;h2 id="circleci-on-google-kubernetes-engine-gke"&gt;CircleCI on Google Kubernetes Engine (GKE)&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/punkdata"&gt;Angel Rivera&lt;/a&gt; shows how to set up CircleCI on GKE with a &lt;a href="https://circleci.com/blog/automate-releases-from-pipelines-using-infrastructure-as-code/"&gt;step-by-step tutorial&lt;/a&gt;. Angel demonstrates how to integrate Infrastructure as Code solutions, such as Pulumi, into CI/CD pipelines. The tutorial builds a container with a Pulumi project with a sample app written in Python that deploys Kubernetes. With Pulumi, your infrastructure is part of your CI/CD. The code for the tutorial is available on &lt;a href="https://github.com/datapunkz/orb-pulumi-gcp"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="hatech-compares-pulumi-to-terraform"&gt;HATech Compares Pulumi to Terraform&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hatechllc"&gt;Jon Hathway&lt;/a&gt; of HATech published a white paper comparing Pulumi to Terraform. Changes in Terraform prompted the comparison. Below, Jon explained why HATech is evaluating Pulumi:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Take for example the teams that are trying to collaborate and drive reliably deployed and maintained product innovations. Is it better to have languages that support each individual team’s needs, or is it better to have one language to support the entire workflow/pipeline?&lt;/p&gt;
&lt;p&gt;How about this thought experiment: Imagine your developers only spoke English, your QA team only spoke French, and the operations team only spoke Spanish? It would be carnage!&lt;/p&gt;
&lt;p&gt;You’d never hire that way. So why, when choosing DevOps tools, do people find it acceptable to have different languages, DSLs that only key individuals understand?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="vmware-vsphere-and-pulumi"&gt;VMWare VSphere and Pulumi&lt;/h2&gt;
&lt;p&gt;&lt;img src="peek-definition.jpg" alt="peek definition"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/Codydearkland"&gt;Cody De Arkland&lt;/a&gt; demonstrates how to &lt;a href="https://www.thehumblelab.com/iac-vsphere-pulumi/"&gt;create a VMWare VSphere Virtual Machine&lt;/a&gt; by adding a ResourcePool, DataStore, NetworkStore and the virtual machine template with Pulumi. He also sets the configuration values such as DNS settings, default gateway, domain, and hostname all in code. All of this runs on the ESXi virtualization server and vCenter (which is why the Datacenter ID is needed for configuration). His example is available on &lt;a href="https://github.com/codyde/pulumi-vsphere-ts"&gt;GitHub&lt;/a&gt;. We like Cody’s caveat that his post is not an endorsement but call to explore new tools. In his conclusion, he nails home the point why Infrastructure as Code is the future of DevOps.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Infrastructure as Code tools like Pulumi (and others in the space, i.e. Terraform from HashiCorp) add a ton of value on top of traditional deployment methods. Being able to store your infrastructure deployments in source control (i.e. GitHub/GitLab) opens up the door to a number of collaboration concepts. When you partner this in with some form of a CI/CD tool (i.e. CircleCI) - things get really interesting. Being able to submit a PR to change an infrastructure deployment, and having something like CircleCI automatically deploy the resources when changes are merged creates a pretty powerful platform for delivering infrastructure to end-users.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="bloggers-welcome"&gt;Bloggers Welcome&lt;/h2&gt;
&lt;p&gt;If you write about your experience using Pulumi, let us know by tagging us on &lt;a href="https://twitter.com/pulumicorp"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;</description><author>Sophia Parafina</author><category>guest-post</category></item><item><title>Pulumi Meetup: APIs, Custom Resources and GitHub Webhooks</title><link>https://www.pulumi.com/blog/pulumi-meetup-recap-apis-custom-resources-and-github-webhooks/</link><pubDate>Tue, 16 Jul 2019 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/pulumi-meetup-recap-apis-custom-resources-and-github-webhooks/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-meetup-recap-apis-custom-resources-and-github-webhooks/index.png" /&gt;
&lt;p&gt;Last Wednesday, we invited members of our local Seattle community to Pulumi HQ for the &lt;a href="https://www.meetup.com/pulumi-seattle/events/262610954/"&gt;July Pulumi Up meetup&lt;/a&gt;. The evening began with some networking time wherein our guests met some Pulumi engineers and users they may have only ever interacted with over &lt;a href="https://slack.pulumi.com/"&gt;Pulumi’s Community Slack&lt;/a&gt; while enjoying free pizza and beverages. This month’s meetup featured two talks by Pulumi engineers.&lt;/p&gt;
&lt;h2 id="application-code-isnt-the-only-code-that-can-have-apis"&gt;Application code isn’t the only code that can have APIs&lt;/h2&gt;
&lt;p&gt;Unfortunately, due to travel issues, &lt;a href="https://twitter.com/stack72"&gt;Paul Stack&lt;/a&gt; wasn’t able to join us in person, but graciously agreed to present remotely… from Europe… at 4:00 in the morning. He presented “Application code isn’t the only code that can have APIs” and went over how programming languages help in building the best infrastructure code. During the talk, he presented a simple &lt;a href="https://github.com/stack72/pulumi-meetup"&gt;Pulumi program for creating an RDS instance&lt;/a&gt; and walked through the simple programming constructs he utilized to help create APIs that anyone could code against. Here’s a &lt;a href="https://www.youtube.com/watch?v=QuOMyZvSt-A"&gt;recording of his talk&lt;/a&gt;, with the video also available on the &lt;a href="https://www.youtube.com/pulumitv"&gt;Pulumi TV YouTube Channel&lt;/a&gt;.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/QuOMyZvSt-A" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h2 id="automate-your-troubles-away-with-webhooks-and-pulumi"&gt;Automate your troubles away with Webhooks and Pulumi&lt;/h2&gt;
&lt;p&gt;Next up, &lt;a href="https://twitter.com/ellism"&gt;Matt Ellis&lt;/a&gt; presented “Automating your troubles away with Webhooks and Pulumi.” Matt isn’t a fan of confrontation, but as the lead of the Pulumi API team, he needs to ensure that our changelog is kept up-to-date with every pull request. In his talk, he walked through his solution that leveraged GitHub Webhooks and Pulumi in building a small bot that enforced some policies on pull requests. You can read more about it in his previous &lt;a href="https://www.pulumi.com/blog/managing-github-webhooks-with-pulumi/"&gt;blog post on Pulumi Webhooks&lt;/a&gt;, or watch the &lt;a href="https://www.youtube.com/watch?v=QuOMyZvSt-A"&gt;recording of his talk&lt;/a&gt;, which is also available on the &lt;a href="https://www.youtube.com/pulumitv"&gt;Pulumi TV YouTube Channel&lt;/a&gt;.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/KhHDhGCdU3c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;After the talks, there was time for more networking and a last chance to get one more slice of pizza. After some more discussions inspired by the speakers, we closed out the evening.&lt;/p&gt;
&lt;p&gt;If you’re in the Seattle area, be sure to join the &lt;a href="https://www.meetup.com/pulumi-seattle"&gt;Pulumi - Seattle meetup group&lt;/a&gt; and join us for our next Pulumi Up. Otherwise, subscribe to the &lt;a href="https://www.youtube.com/pulumitv"&gt;Pulumi TV YouTube Channel&lt;/a&gt; and watch the presentations at your leisure.&lt;/p&gt;</description><author>Aydrian Howard</author><category>pulumi-events</category></item><item><title>Happy Birthday to Pulumi open source!</title><link>https://www.pulumi.com/blog/happy-birthday-to-pulumi-open-source/</link><pubDate>Tue, 18 Jun 2019 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/happy-birthday-to-pulumi-open-source/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/happy-birthday-to-pulumi-open-source/index.png" /&gt;
&lt;p&gt;One year ago today &amp;ndash; on June 18, 2018 &amp;ndash;
&lt;a href="https://www.pulumi.com/blog/introducing-pulumi-a-cloud-development-platform/"&gt;we open sourced Pulumi&lt;/a&gt;,
a new approach to multi-cloud infrastructure as code using your favorite
languages. And what a year it has been!&lt;/p&gt;
&lt;p&gt;Here are some highlights we&amp;rsquo;ve added in partnership with the community
since launching:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Over 100 &lt;a href="https://github.com/pulumi/examples"&gt;examples&lt;/a&gt;,
&lt;a href="https://www.pulumi.com/registry/"&gt;tutorials&lt;/a&gt;, and a brand new
&lt;a href="https://www.pulumi.com/docs/get-started/"&gt;Getting Started guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/pulumi-a-better-way-to-kubernetes"&gt;A native Kubernetes provider with 100% Kubernetes API/version coverage.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A steady stream of improvements across
&lt;a href="https://www.pulumi.com/docs/iac/get-started/aws/"&gt;AWS&lt;/a&gt;,
&lt;a href="https://www.pulumi.com/docs/iac/get-started/azure/"&gt;Azure&lt;/a&gt;, and
&lt;a href="https://www.pulumi.com/docs/iac/get-started/gcp/"&gt;Google Cloud&lt;/a&gt; providers.&lt;/li&gt;
&lt;li&gt;Pulumi Crosswalk for AWS, a framework with built-in AWS infrastructure best practices.&lt;/li&gt;
&lt;li&gt;Over 20 additional providers, including
&lt;a href="https://github.com/pulumi/pulumi-cloudflare"&gt;CloudFlare&lt;/a&gt;,
&lt;a href="https://github.com/pulumi/pulumi-digitalocean"&gt;Digital Ocean&lt;/a&gt;, and
&lt;a href="https://www.pulumi.com/blog/managing-your-mysql-databases-with-pulumi/"&gt;MySQL&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Brought our &lt;a href="https://www.pulumi.com/docs/reference/pkg/python/"&gt;Python 3 SDK&lt;/a&gt;
to parity with our
&lt;a href="https://www.pulumi.com/docs/reference/pkg/nodejs/"&gt;Node.js-based JavaScript and TypeScript SDKs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/pricing/"&gt;Team and Enterprise SaaS editions for teams managing infrastructure in production&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/admin/organizations/"&gt;GitHub, GitLab, Atlassian, and SAML/SSO identity providers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/continuous-delivery/"&gt;CI/CD integrations with GitHub, GitLab, Codefresh, CircleCI, major clouds, and more&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/managing-secrets-with-pulumi/"&gt;Pluggable secrets management and transitive state encryption&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/iac/concepts/state-and-backends/"&gt;Pluggable state backends for AWS S3, Azure Blob Store, and Google Cloud Store&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/using-terraform-remote-state-with-pulumi/"&gt;Tools for managing complex, multi-stack environments, including Terraform integration&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Numerous engine reliability and performance improvements, including parallelism.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/"&gt;75 blogs, increasingly focused on end to end solutions we see working with customers&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the steady stream of product improvements, the community
has grown fast:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1,000s of cloud engineers&lt;/strong&gt; trying out Pulumi across over &lt;strong&gt;1,000
companies&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1,000 end users&lt;/strong&gt; collaborating in our Community Slack &amp;ndash;
including emerging MVPs!&lt;/li&gt;
&lt;li&gt;Open source contributions from &lt;strong&gt;over 100 community members&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Nearly &lt;strong&gt;5,000 commits&lt;/strong&gt;, across &lt;strong&gt;over 100 open source Git
repositories&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What we&amp;rsquo;ve enjoyed most is hearing about the innovation you, the end
user and customer, have accomplished thanks to Pulumi&amp;rsquo;s unique approach.
These experiences range from enabling better collaboration between
application and infrastructure engineers; vastly improved productivity;
more secure, robust, and reliable delivery pipelines; and an improved
ability to go to production in multiple clouds, including by leveraging
the cloud native Kubernetes stack.&lt;/p&gt;
&lt;p&gt;A few notable success stories include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mercedes-Benz R&amp;amp;D North America&lt;/strong&gt; used Python infrastructure as
code to break down team silos between developers and infrastructure
engineers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tableau&lt;/strong&gt; was able to get up and running with Kubernetes in AWS,
using Amazon EKS, and make progress on their journey to bringing
continuous delivery to their organization.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learning Machine&lt;/strong&gt; went from 25KLOC YAML to 500 lines of
JavaScript, got containers running in AWS and Kubernetes, and halved
their cloud bill along the way.
&lt;a href="https://www.pulumi.com/blog/delivering-cloud-native-infrastructure-as-code-a-pulumi-white-paper/Pulumi-Delivering-CNI-as-Code.pdf"&gt;Read more&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mapbox&lt;/strong&gt; built a scalable IoT tracking solution with serverless
Lambdas. &lt;a href="https://www.pulumi.com/blog/mapbox-iot-as-code-with-pulumi-crosswalk-for-aws/"&gt;Read more.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Multiple early stage startups, including &lt;strong&gt;Jargon&lt;/strong&gt;, a TechStars
company, have used Pulumi to get up and running quickly in the cloud
&amp;ndash; doing in days what used to take weeks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dozens&lt;/strong&gt; of more great stories that we can&amp;rsquo;t wait to share in the
weeks to come!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We want to sincerely thank our community and our customers and partners
&amp;ndash; without you, the year wouldn&amp;rsquo;t have nearly been as successful. The
best part is that we&amp;rsquo;re only just getting started. Expect another year
of more innovation, growing community engagement, customer success, and
more focus on end to end solutions borne out of experience.&lt;/p&gt;
&lt;p&gt;Whether it&amp;rsquo;s adopting infrastructure as code on your favorite cloud,
deploying containers to Kubernetes, or architecting and executing on
your multi-cloud journey, Pulumi is here for you!&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;/p&gt;
&lt;p&gt;Joe and the Pulumi Team&lt;/p&gt;</description><author>Joe Duffy</author><category>announcements</category></item><item><title>Upcoming AWS + Pulumi Webinar on Feb 5</title><link>https://www.pulumi.com/blog/upcoming-aws-pulumi-webinar-on-feb-5/</link><pubDate>Wed, 09 Jan 2019 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/upcoming-aws-pulumi-webinar-on-feb-5/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/upcoming-aws-pulumi-webinar-on-feb-5/index.png" /&gt;
&lt;p&gt;Pulumi is hosting a webinar with AWS Fargate &lt;strong&gt;on
February 5th, 10AM PST&lt;/strong&gt; (register
&lt;a href="https://www.pulumi.com/resources/#upcoming"&gt;here&lt;/a&gt;).
We&amp;rsquo;ll be chatting about how to implement cloud native infrastructure
across your organization using &lt;a href="https://www.pulumi.com/docs/iac/clouds/aws/guides/"&gt;AWS and Pulumi&lt;/a&gt;: general purpose programming
languages to deliver everything from VMs to Kubernetes to Serverless.&lt;/p&gt;
&lt;h2 id="register-now"&gt;Register Now&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/resources/#upcoming"&gt;Registration link&lt;/a&gt;.
Specifically, you will learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How using general-purpose programming languages provides familiar
and powerful programming concepts to infrastructure-as-code
challenges&lt;/li&gt;
&lt;li&gt;How Pulumi can help build a library of code packages to enhance
efficiency when implementing standard policies, network best
practices, and more&lt;/li&gt;
&lt;li&gt;Best practices for becoming a deployment-focused organization,
rather than configuration-focused, to continuously deliver new
cloud-native infrastructure with containerization&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Joining us is Pulumi customer &lt;a href="https://www.hyland.com/"&gt;Learning
Machine&lt;/a&gt;. Adopting Pulumi helped
Learning Machine reduce 25,000 LoC of ad-hoc DevOps scripts to 500 LoC
of JavaScript, improving time to ship code, time to provision and
onboard new customers, and unify their Development and DevOps teams and
techniques.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/upcoming-aws-pulumi-webinar-on-feb-5/code-comparison.png" alt="code comparison"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/blog/upcoming-aws-pulumi-webinar-on-feb-5/AWS-Pulumi-CaseStudy.pdf"&gt;Download the case study&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This webinar will be useful to developers, System Architects, IT
managers and DevOps managers. (register
&lt;a href="https://www.pulumi.com/resources/#upcoming"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Ask any questions you have to our speakers, Trevor Hansen (Startup
Partner Solutions Architect), Luke Hoban (CTO, Pulumi), and Kim Hamilton
Duffy (CTO &amp;amp; Principal Architect, Learning Machine).&lt;/p&gt;
&lt;p&gt;To learn more about the webinar, check out our
&lt;a href="https://www.pulumi.com/blog/upcoming-aws-pulumi-webinar-on-feb-5/AWS-Ebook.pdf"&gt;e-book&lt;/a&gt; and &lt;a href="https://www.pulumi.com/blog/upcoming-aws-pulumi-webinar-on-feb-5/AWS-Pulumi-CaseStudy.pdf"&gt;case study&lt;/a&gt;.&lt;/p&gt;</description><author>Erin Xue</author><category>aws</category><category>continuous-delivery</category></item><item><title>Meet the Pulumi team at AWS re:Invent</title><link>https://www.pulumi.com/blog/meet-the-pulumi-team-at-aws-reinvent/</link><pubDate>Thu, 15 Nov 2018 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/meet-the-pulumi-team-at-aws-reinvent/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/meet-the-pulumi-team-at-aws-reinvent/index.png" /&gt;
&lt;p&gt;Heading to AWS re:Invent? Concerned about how you&amp;rsquo;ll manage to get
&lt;a href="https://www.pulumi.com/cloudformation/"&gt;that much YAML&lt;/a&gt; into your carry
on bag? Or maybe you just like purple.&lt;/p&gt;
&lt;p&gt;Whatever the reason, the Pulumi team will be there all week at **Booth
316, Startup Central, Aria Quad, **and we&amp;rsquo;d love to chat with you about
&lt;a href="https://www.pulumi.com/docs/iac/clouds/aws/guides/"&gt;AWS and Pulumi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Catch up with us on serverless functions, containers and
&lt;a href="https://www.pulumi.com/kubernetes/"&gt;Kubernetes&lt;/a&gt;, managed services and
any other cloud native infrastructure as code, and see how you can more
productively manage your AWS cloud resources with general purpose
programming languages. We can even help you
&lt;a href="https://www.pulumi.com/cloudformation/"&gt;migrate your CloudFormation to Pulumi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want to grab a specific time to talk through your needs,
&lt;a href="https://info.pulumi.com/meetings/team-pulumi/aws-reinvent-catchup"&gt;then use this link&lt;/a&gt;,
otherwise we&amp;rsquo;ll just see you at the booth!&lt;/p&gt;</description><author>Marc Holmes</author><category>announcements</category></item><item><title>Data science on demand: spinning up a Wallaroo cluster</title><link>https://www.pulumi.com/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/</link><pubDate>Fri, 02 Nov 2018 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/index.png" /&gt;
&lt;p&gt;&lt;em&gt;This guest post is from Simon Zelazny of
&lt;a href="https://www.wallaroo.ai/"&gt;Wallaroo Labs&lt;/a&gt;.
Find out how Wallaroo powered their cluster provisioning with Pulumi,
for data science on demand.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last month, we took a
&lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples/tree/master/provisioned-classifier/classifier"&gt;long-running pandas classifier&lt;/a&gt;
and made it run faster by leveraging Wallaroo&amp;rsquo;s parallelization
capabilities. This time around, we&amp;rsquo;d like to kick it up a notch and see
if we can keep scaling out to meet higher demand. We&amp;rsquo;d also like to be
as economical as possible: provision infrastructure as needed and
de-provision it when we&amp;rsquo;re done processing.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t feel like reading the post linked above, here&amp;rsquo;s a short
summary of the situation: there&amp;rsquo;s a batch job that you&amp;rsquo;re running every
hour, on the hour. This job receives a CSV file and classifies each row
of the file, using a Pandas-based algorithm. The run-time of the job is
starting to near the one-hour mark, and there&amp;rsquo;s concern that the
pipeline will break down once the input data grows past a particular
point.&lt;/p&gt;
&lt;p&gt;In the blog post, we show how to split up the input data into smaller
dataframes, and distribute them among workers in an ad-hoc Wallaroo
cluster, running on one physical machine. Parallelizing the work in this
manner buys us a lot of time, and the batch job can continue processing
increasing amounts of data.&lt;/p&gt;
&lt;p&gt;Sure, we can handle a million rows in reasonable time, but what if the
data set grows by orders of magnitude? By running our classifier on a
local Wallaroo cluster, we were able to cut the processing time of a
million rows to ~16 minutes, thus fitting within our allotted time slot
of one hour. But if the input data is, say, 10x more, we&amp;rsquo;re going to
have a hard time processing it all locally.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how we can keep up with the data growth by launching a
cloud-based Wallaroo cluster on-demand, running the job, collecting the
data, and shutting down the cluster, all in a fully automated fashion.&lt;/p&gt;
&lt;h2 id="tools-of-the-trade"&gt;Tools of the trade&lt;/h2&gt;
&lt;p&gt;Wallaroo&amp;rsquo;s big idea is that your application doesn&amp;rsquo;t have to know
whether it&amp;rsquo;s running on one process, several local processes, or a
distributed system comprising many physical machines. In this sense,
there&amp;rsquo;s no extra work involved in &amp;lsquo;migrating&amp;rsquo; our classifier application
from the previous blog post.&lt;/p&gt;
&lt;p&gt;We will need some tools to help us set up and manage our cluster in the
cloud. Wallaroo can work with a lot of different tools. Our friends at
Pulumi provide an excellent tool that removes the
headaches involved in provisioning infrastructure. We&amp;rsquo;ll use Pulumi to
define, set up, and finally tear down our processing cluster in this
example.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll also need &lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; to start, stop, and
inspect the state of our cluster, and, last but not least, we&amp;rsquo;ll need
an &lt;a href="https://aws.amazon.com/"&gt;AWS&lt;/a&gt; account where our machines will live.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s jump into it!&lt;/p&gt;
&lt;h2 id="a-sample-run"&gt;A sample run&lt;/h2&gt;
&lt;p&gt;First of all, if you&amp;rsquo;d like to follow along (and spend some money
provisioning EC2 servers), please
&lt;a href="https://www.pulumi.com/docs/install/"&gt;download and set up Pulumi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, &lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples"&gt;clone the wallaroo blog examples repo&lt;/a&gt; and
navigate to &lt;code&gt;provisioned-classifier&lt;/code&gt;. If you followed along with the
previous Pandas blog post, you&amp;rsquo;ll find our old application nested away
here, under&lt;code&gt;classifier&lt;/code&gt;. What&amp;rsquo;s more interesting are the two new
directories: &lt;code&gt;pulumi&lt;/code&gt; and &lt;code&gt;ansible&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Without delving into details, let&amp;rsquo;s see how to run our application on a
freshly-provisioned cluster in the EC2 cloud:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make up run-cluster get-results down &lt;span class="nv"&gt;INPUT_LINES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1000000&lt;/span&gt; &lt;span class="nv"&gt;CLUSTER_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://www.pulumi.com/uploads/content/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/tty-fast.gif" alt="tty-fast"&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s break that down and see what&amp;rsquo;s really going on here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;make up CLUSTER_SIZE=3&lt;/code&gt; configures the cluster to consist of 3
machines, and delegates to &lt;code&gt;pulumi up&lt;/code&gt; the actual business of spinning
up the infrastructure. Our physical cluster will contain 3 nodes for
processing, and one extra metrics_host node for hosting our Metrics
UI, and collecting results.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once provisioning is complete, the next make
task: &lt;code&gt;run-cluster INPUT_LINES=1000000&lt;/code&gt; uses our Ansible playbooks to
upload application code from &lt;code&gt;classifier/*&lt;/code&gt; to all 3 machines
provisioned above, and then start up a Wallaroo cluster with 7 worker
processes per machine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, Ansible starts sending 1 million lines of our
&lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples/blob/master/provisioned-classifier/bin/send.py"&gt;synthetic CSV data&lt;/a&gt;,
and waits for 1 million lines to arrive at the &lt;code&gt;data_receiver&lt;/code&gt; process.
When those lines arrive, they are compressed, and the cluster is shut
down.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;make get-results&lt;/code&gt; pulls the compressed result file
to &lt;code&gt;output/results.tgz&lt;/code&gt;,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And finally, &lt;code&gt;make down&lt;/code&gt; destroys the cloud infrastructure that was
used to power our computation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="the-pulumi-cluster-definition"&gt;The Pulumi cluster definition&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at how our infrastructure is defined. This is the core
of the
&lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples/blob/master/provisioned-classifier/pulumi/index.js"&gt;definition&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;associatePublicIpAddress&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;instanceType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instanceType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;securityGroups&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;secGrp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ami&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ami&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keyPair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;metrics_host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;classifier-metrics_host&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;initializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;classifier-initializer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;clusterSize&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;classifier-&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see from the above, our little &lt;code&gt;instance()&lt;/code&gt; function
encapsulates the common settings for every machine that we want to
provision.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;metrics_host&lt;/code&gt; and &lt;code&gt;initializer&lt;/code&gt; are &lt;code&gt;ec2.Instance&lt;/code&gt; objects with
descriptive names, while the &lt;code&gt;workers&lt;/code&gt; are &lt;code&gt;ec2.Instance&lt;/code&gt;s that are
distinguished solely by their ordinal number. Pulumi lets us define &amp;ndash;
in code &amp;ndash; things like Security Groups, SSH keypairs, and practically
every other aspect of cloud infrastructure.&lt;/p&gt;
&lt;p&gt;An example of this capability is the &lt;code&gt;keyPair&lt;/code&gt; object that&amp;rsquo;s used to
access the instances via SSH. Our Makefile ensures that an ssh key is
generated on-the-fly for our cluster, and Pulumi knows how to use it to
set up SSH access for newly-provisioned nodes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;let pubKey = fs.readFileSync(&amp;#34;../ssh_pubkey_in_ec2_format.pub&amp;#34;).toString();
let keyPair = new aws.ec2.KeyPair(&amp;#34;ClassifierKey&amp;#34;, {publicKey: pubKey});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the relevant bits of our computing infrastructure thus defined, we
can tell Pulumi to take action in the real world and make it conform to
our definition:&lt;/p&gt;
&lt;p&gt;When we run &lt;code&gt;make up CLUSTER_SIZE=3&lt;/code&gt;, we&amp;rsquo;ll see Pulumi output something
like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Performing changes:
+ pulumi:pulumi:Stack classifier-classifier-demo creating
+ aws:ec2:KeyPair ClassifierKey creating
(...)
+ aws:ec2:Instance classifier-2 created
---outputs:---
metrics_host: [
[0]: {
name : &amp;quot;classifier-metrics_host&amp;quot;
private_ip: &amp;quot;172.31.47.236&amp;quot;
public_dns: &amp;quot;ec2-54-245-53-87.us-west-2.compute.amazonaws.com&amp;quot;
}
(...)
]
info: 7 changes performed:
+ 7 resources created
Update duration: 1m59.524017637s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can use Pulumi&amp;rsquo;s output to stitch together an Ansible inventory,
which will let us interact programmatically with our provisioned
instances.&lt;/p&gt;
&lt;p&gt;If we want to modify our cluster, we can edit &lt;code&gt;pulumi/index.js&lt;/code&gt;, and
then rerun &lt;code&gt;make up CLUSTER_SIZE=N&lt;/code&gt;. If the changes don&amp;rsquo;t require
restarting the instances (for example if they only concern the Security
Group), Pulumi will do the right thing and not disturb the rest of the
infrastructure.&lt;/p&gt;
&lt;p&gt;If you examine the Pulumi definition file in depth, you&amp;rsquo;ll see that it
relies on a mystery AMI: &lt;code&gt;ami-058d2ca16567a23f7&lt;/code&gt;. This is an
experimental ubuntu-based image, with Wallaroo binaries
(&lt;code&gt;machida&lt;/code&gt;, &lt;code&gt;cluster_shutdown&lt;/code&gt;,&lt;code&gt;cluster_shrinker&lt;/code&gt;, and &lt;code&gt;data_receiver&lt;/code&gt;)
pre-loaded. For now, it only exists in the &lt;code&gt;us-west-2&lt;/code&gt; AWS region, but
we hope to make Wallaroo AMIs available for experimentation in all
regions starting with the next Wallaroo release.&lt;/p&gt;
&lt;h2 id="running-the-computation"&gt;Running the computation&lt;/h2&gt;
&lt;p&gt;Now that we know what magic powers conjured up our AWS infrastructure,
let&amp;rsquo;s take a look at how we use it to run our task. Fundamentally, the
components of our cluster can be described as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The data source &amp;ndash; In our case it&amp;rsquo;s the
file &lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples/blob/master/provisioned-classifier/bin/send.py"&gt;send.py&lt;/a&gt;,
which can generate and transmit randomly-generated CSV data for our
computation to consume.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The machida processes: one Initializer and a bunch of Workers. The
distinction between the two is only relevant at cluster startup.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The data receiver &amp;ndash; A process that listens on a TCP port for the
output of our computation. This is the &lt;code&gt;data_receiver&lt;/code&gt;, provided as part
of a Wallaroo installation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The metrics UI &amp;ndash; Our Elixir-powered realtime dashboard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Our Ansible playbook takes care of coordinating the launch of the
various components and making sure that their input, output and control
ports match up. In particular, that the cluster initializer starts up
knowing the total number of workers in the cluster, and every other
worker connects to the initializer&amp;rsquo;s internal IP and control port.&lt;/p&gt;
&lt;p&gt;This is what ends up running on the servers when we launch our Ansible
playbooks:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/wallaroo.png" alt="wallaroo"&gt;&lt;/p&gt;
&lt;p&gt;Once the cluster is up and running, and the initializer node&amp;rsquo;s
&lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples/blob/master/provisioned-classifier/classifier/classifier.py#L17"&gt;tcp source&lt;/a&gt;
is listening for connections, we start up the &lt;code&gt;sender&lt;/code&gt; and instruct it to
send a stream of data to the TCP Source. In a realistic batch scenario,
this sender could be implemented as a Connector that
reads a particular file from a remote filesystem or S3. For our
purposes, we&amp;rsquo;ll simulate this by generating a set number of CSV lines
on-demand, and then shutting down.&lt;/p&gt;
&lt;p&gt;While the work is being performed, we can take a look at the metrics URL
printed out on the screen to find out how the work is being distributed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To see the cluster&amp;rsquo;s real-time metrics, please visit
&lt;code&gt;http://ec2-54-200-198-6.us-west-2.compute.amazonaws.com:4000&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/wallaroo-2.png" alt="wallaroo-2"&gt;&lt;/p&gt;
&lt;p&gt;In the screenshot above, you can see that
the &lt;code&gt;Initializer&lt;/code&gt; and &lt;code&gt;B03a909b23&lt;/code&gt;nodes are processing about 4k messages
per second each, and all the other workers have the classification work
split evenly among them. Don&amp;rsquo;t be surprised that two of the workers are
processing orders of magnitude more messages! Remember our
&lt;a href="https://github.com/WallarooLabs/wallaroo_blog_examples/blob/master/provisioned-classifier/classifier/classifier.py#L11-L21"&gt;pandas application pipeline&lt;/a&gt;?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ab.new_pipeline(&amp;quot;Classifier&amp;quot;,
wallaroo.TCPSourceConfig(in_host, in_port, decode))
ab.to_stateful(batch_rows, RowBuffer, &amp;quot;CSV rows + global header state&amp;quot;)
ab.to_parallel(classify)
ab.to_sink(wallaroo.TCPSinkConfig(out_host, out_port, encode))
return ab.build()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CSV rows come in one-by-one, but we batch them and convert them to
dataframes of a hundred, so that our classification algorithm can tackle
more than one row at a time. Worker &lt;code&gt;B03a909b23&lt;/code&gt; just happens to be the
worker where our state named &amp;ldquo;CSV rows + global header state&amp;rdquo; lives.
Let&amp;rsquo;s take a look at its metrics:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/wallaroo-3.png" alt="wallaroo3"&gt;&lt;/p&gt;
&lt;p&gt;Indeed, we can see that this worker is processing about 4k/sec messages
in the &amp;ldquo;Batch Rows Of Csv, Emit Dataframes&amp;rdquo; step. Every other worker is
busy classifying! Let&amp;rsquo;s see the breakdown for a different, random
worker:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/data-science-on-demand-spinning-up-a-wallaroo-cluster-is-easy-with-pulumi/wallaroo-4.png" alt="wallaroo-4"&gt;&lt;/p&gt;
&lt;p&gt;Looking good. All that&amp;rsquo;s left for us to do is wait until the job
completes and we receive our zipped data onto our disk.&lt;/p&gt;
&lt;h2 id="the-numbers"&gt;The numbers!&lt;/h2&gt;
&lt;p&gt;As a reminder, let&amp;rsquo;s take a look at the numbers we obtained by running
our classifier on a single &lt;code&gt;c5.4xlarge&lt;/code&gt; instance in AWS:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# SINGLE-MACHINE RUNNING TIMES (NO PROVISIONING)
CSV rows 1 worker 4 workers 8 workers
----------- ---------- ----------- -----------
10 000 39s 20s 11s
100 000 6m28s 3m16s 1m41s
1 000 000 1h03m46s 32m12s 16m33s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let&amp;rsquo;s see how much speedup we can achieve from scaling out with our
provisioned-on-demand infrastructure.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# MULTI-MACHINE RUNNING TIMES (PROVISIONING + COMPUTATION)
----------------------------------------------------------
CSV rows 4 machines/ 8 machines/ 16 machines/
28 workers 56 workers 112 workers
------------ -------------- -------------- ---------------
10 000 2m13s 2m36s 2m43s
100 000 3m38s 3m42s 3m48s
1 000 000 7m38s 6m41s 5m56s
10 000 000 40m56s 33m10s 23m24s
30 000 000 &amp;gt; 2h 1h45m 1h12m
----------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Even though there is some constant overhead involved in spinning up the
required infrastructure (clearly too much overhead to justify spinning
up clusters for less than 1 million rows), we&amp;rsquo;re now able to classify a
hefty 10 million rows of CSV data in under half an hour, and 30 million
in a little over an hour. This gives us some perspective on when our
application will need extra resources, or perhaps some performance
optimizations.&lt;/p&gt;
&lt;p&gt;As long as the data fits in the 1 million : 10 million range, it seems
that a cluster of 4 machines represents a sweet-spot between price and
performance &amp;ndash; we can process the data and still fit in the hour-long
window allotted for our batch process, but not have to incur unnecessary
infrastructure costs if we don&amp;rsquo;t need the extra speed.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The above figures illustrate how Wallaroo can be used as an ad-hoc
compute cloud, using Pulumi and Ansible to provision, run workloads
remotely, and shut down the infrastructure once the results are in.&lt;/p&gt;
&lt;p&gt;In the case or our batch job, we can leverage this pattern to scale
horizontally on-demand, even when the incoming workloads exceed the
capacity of one physical machine &amp;ndash; all while running the exact same
Wallaroo application that we run locally as part of our regular
development. Wallaroo handles the scale-aware layer of our program, so
we can focus on the business logic and flow of our data.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re hitting limits when running your hourly, daily or nightly
batch jobs and are looking into scaling out horizontally, don&amp;rsquo;t hesitate
to reach out or drop in to our IRC channel. We&amp;rsquo;d love to chat!&lt;/p&gt;</description><author>Marc Holmes</author><author>Simon Zelazny</author><category>guest-post</category><category>data-science</category></item></channel></rss>