<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Marc Holmes</title><link>https://www.pulumi.com/blog/author/marc-holmes/</link><description>Pulumi blog posts: Marc Holmes.</description><language>en-us</language><pubDate>Wed, 05 Dec 2018 00:00:00 +0000</pubDate><item><title>Delivering Cloud Native Infrastructure as Code</title><link>https://www.pulumi.com/blog/delivering-cloud-native-infrastructure-as-code-a-pulumi-white-paper/</link><pubDate>Wed, 05 Dec 2018 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/delivering-cloud-native-infrastructure-as-code-a-pulumi-white-paper/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/delivering-cloud-native-infrastructure-as-code-a-pulumi-white-paper/index.png" /&gt;
&lt;p&gt;&lt;strong&gt;Enterprise software has undergone a slow shift from containerless
servers to serverless containers.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The evolution of the cloud, combined with the shift to increasingly
ephemeral infrastructure, and the connection of application code and
infrastructure code, demands a different view of cloud development and
devops.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/delivering-cloud-native-infrastructure-as-code-a-pulumi-white-paper/graph.png" alt="infrastructure - cloud native - functions"&gt;&lt;/p&gt;
&lt;p&gt;To a first approximation, all developers are cloud developers, all
applications are cloud native, and all operations are cloud-first. Yet,
there is a lack of a consistent approach to delivering cloud native
applications and infrastructure. The tools and processes differ by
technology generation, and even by cloud vendor, and so deny the full
potential of cloud native application delivery.&lt;/p&gt;
&lt;p&gt;In our latest white paper,
&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;Delivering Cloud Native Infrastructure as Code&lt;/a&gt;,
we make the case for a consistent programming model for the cloud and examine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How the cloud has already evolved three times as it increasingly
moves toward stateless compute to deliver on the opportunities
afforded by unprecedented economies of scope and scale.&lt;/li&gt;
&lt;li&gt;How stateless compute has shifted infrastructure management concerns
from &amp;lsquo;at rest&amp;rsquo; to &amp;lsquo;in motion&amp;rsquo;, and moved these concerns up the stack
to development.&lt;/li&gt;
&lt;li&gt;How the growth of DSL-based tools has lead to complexity for DevOps
teams, failed to deliver on the promised collaboration between
development and operations functions, and does not satisfy the need
for increasing delivery speed in the cloud.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can read the paper in full &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;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let us know what you think!&lt;/p&gt;</description><author>Marc Holmes</author><category>announcements</category><category>cloud-native</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><item><title>Building new Pulumi projects and stacks from templates</title><link>https://www.pulumi.com/blog/building-new-pulumi-projects-and-stacks-from-templates/</link><pubDate>Mon, 01 Oct 2018 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/building-new-pulumi-projects-and-stacks-from-templates/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/building-new-pulumi-projects-and-stacks-from-templates/index.png" /&gt;
&lt;p&gt;When you&amp;rsquo;re able to build an app for any cloud using familiar languages,
the obvious question is &amp;ldquo;Where to start?&amp;rdquo;. We hear you, and so we&amp;rsquo;ve
built some new features to help you scaffold your app and program the
cloud even faster than before.&lt;/p&gt;
&lt;p&gt;In this post, we&amp;rsquo;ll look at how to use &lt;code&gt;pulumi new&lt;/code&gt; and our &lt;a href="https://github.com/pulumi/templates"&gt;selection of templates&lt;/a&gt; to build your Pulumi
app.&lt;/p&gt;
&lt;p&gt;There is template support for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS, Microsoft Azure, Google Cloud, Kubernetes, and OpenStack in
each of&amp;hellip;&lt;/li&gt;
&lt;li&gt;TypeScript, JavaScript, Python, and Go (K8S is currently just JS/TS)&lt;/li&gt;
&lt;li&gt;You can see all these options at
&lt;a href="https://github.com/pulumi/templates"&gt;https://github.com/pulumi/templates&lt;/a&gt; where we&amp;rsquo;ll gladly accept
updates and new templates as PRs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="creating-a-project-from-the-pulumi-dashboard"&gt;Creating a project from the Pulumi dashboard&lt;/h2&gt;
&lt;p&gt;Head over to &lt;a href="https://app.pulumi.com/signin"&gt;app.pulumi.com&lt;/a&gt; and - supposing you&amp;rsquo;re logged in -
you&amp;rsquo;ll be presented with the usual homepage. But now we&amp;rsquo;ve added a
shiny new &amp;lsquo;Add New Project&amp;rsquo; button. Here&amp;rsquo;s how that works:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/uploads/new-project-ui-1.gif" alt="new-project-ui-1"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clicking the &amp;lsquo;Add New Project&amp;rsquo; button takes you to a series of
available templates - essentially a matrix of cloud provider and
language: from Go on Google Cloud, through TypeScript on AWS, to Python on
OpenStack, and everything in-between.&lt;/li&gt;
&lt;li&gt;Choosing an option will present a screen with some standard
configuration options that you can change or leave defaulted.&lt;/li&gt;
&lt;li&gt;Click again, and Pulumi creates a project which is ready for you to
initialize your first stack. The project page shows the command line
instruction to run to get started with your chosen stack.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can use that code by creating a folder, and then running the command
in the folder to get build our boilerplate stack. All of the stack
templates create a storage bucket (e.g. an AWS S3 bucket).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir MyStack &amp;amp;&amp;amp; cd MyStack
pulumi new https://github.com/pulumi/templates/aws-javascript -s mehzer/my-stack-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output of this command will create the new stack from the template,
display a preview of the stack, and ask if you&amp;rsquo;d like to create it for
real. Assuming you have setup the relevant cloud provider, that&amp;rsquo;s all
there is to it.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/building-new-pulumi-projects-and-stacks-from-templates/pulumi-new-1.gif" alt="Pulumi-New-1"&gt;&lt;/p&gt;
&lt;p&gt;Back in the dashboard, you can now see the state of your stack, and
you&amp;rsquo;re ready to flesh it out with the detail you need.&lt;/p&gt;
&lt;h2 id="creating-a-project-from-the-pulumi-cli"&gt;Creating a project from the Pulumi CLI&lt;/h2&gt;
&lt;p&gt;Alternatively, you can do the same thing from the CLI. Create a folder,
then type &lt;code&gt;pulumi new&lt;/code&gt; in there to retrieve a list of available
templates. Templates ahoy!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/building-new-pulumi-projects-and-stacks-from-templates/pulumi-new-cli.png" alt="pulumi-new-cli"&gt;&lt;/p&gt;
&lt;p&gt;After you&amp;rsquo;ve selected the template you&amp;rsquo;d like, you can again
&lt;code&gt;pulumi preview&lt;/code&gt; or &lt;code&gt;pulumi up&lt;/code&gt; to get your stack running.&lt;/p&gt;
&lt;h2 id="wait-wasnt-that-just-a-link-to-a-repo-does-that-mean"&gt;Wait, wasn&amp;rsquo;t that just a link to a repo? Does that mean..?&lt;/h2&gt;
&lt;p&gt;Yes it was, and yes you can run &lt;code&gt;pulumi up&lt;/code&gt; against an arbitrary repo
supposing that there is a &lt;code&gt;Pulumi.yaml&lt;/code&gt; and package metadata (e.g.
&lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;Gopkg.toml&lt;/code&gt; or &lt;code&gt;requirements.txt&lt;/code&gt; files) alongside
the stack code meaning you can build your own templates and share them.&lt;/p&gt;
&lt;p&gt;We hope you like these helpers. If you&amp;rsquo;re keen to get stuck in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://slack.pulumi.com"&gt;Join the Slack conversation&lt;/a&gt; - it&amp;rsquo;s
heating up in there.&lt;/li&gt;
&lt;li&gt;Try out the &lt;a href="https://app.pulumi.com/signin"&gt;many examples we have&lt;/a&gt;, and
&lt;a href="https://www.pulumi.com/docs/"&gt;dive into the docs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumi/templates"&gt;Submit new templates as PRs&lt;/a&gt; -
contribution == t-shirts at least.&lt;/li&gt;
&lt;/ul&gt;</description><author>Marc Holmes</author><category>features</category></item><item><title>Build your first serverless app using only JavaScript</title><link>https://www.pulumi.com/blog/building-your-first-serverless-app-using-only-javascript/</link><pubDate>Thu, 05 Jul 2018 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/building-your-first-serverless-app-using-only-javascript/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/building-your-first-serverless-app-using-only-javascript/index.png" /&gt;
&lt;div class="note note-warning"&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.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-warning-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;This post is outdated. The &lt;code&gt;hello-aws-javascript&lt;/code&gt; template and &lt;code&gt;@pulumi/cloud-aws&lt;/code&gt; package used in this post are no longer maintained. We recommend using TypeScript for new Pulumi projects. See the &lt;a href="https://www.pulumi.com/docs/get-started/"&gt;Get Started guide&lt;/a&gt; to build your first serverless app with TypeScript.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this tutorial, we&amp;rsquo;ll use Pulumi to build a
complete serverless application using only JavaScript. When we say &amp;lsquo;using
only JavaScript&amp;rsquo;, we&amp;rsquo;re not kidding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;write code just like an Express app&amp;hellip; but end up with a fully
deployable serverless app&lt;/li&gt;
&lt;li&gt;lambdas are&amp;hellip; just lambdas&lt;/li&gt;
&lt;li&gt;no YAML required&amp;hellip; freedom from indentation&lt;/li&gt;
&lt;li&gt;all the features of the V8 runtime&amp;hellip; async await ahoy&lt;/li&gt;
&lt;li&gt;all the behaviors of immutable infrastructure as code tools&amp;hellip; but
we really mean &amp;lsquo;as code&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pulumi also supports containers (including Kubernetes), managed
services, infrastructure and everything else in between that you might
need for building cloud applications. Better than that, you can even
&lt;a href="https://www.pulumi.com/blog/build-a-video-thumbnailer-with-pulumi-using-lambdas-containers-and-infrastructure-on-aws/"&gt;combine them all in the same program&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="our-first-serverless-app-in-5-lines-of-javascript"&gt;Our first serverless app in 5 lines of JavaScript&lt;/h2&gt;
&lt;p&gt;After &lt;a href="https://www.pulumi.com/docs/install/"&gt;installing the Pulumi CLI&lt;/a&gt;, a small &lt;code&gt;index.js&lt;/code&gt; file (the main Pulumi code)
represents a simple but complete serverless application:&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="c1"&gt;// Add the required package
&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;cloud&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;@pulumi/cloud-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="c1"&gt;// Declare an HTTP endpoint
&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;endpoint&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;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;hello&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="c1"&gt;// Serve up some static content on that endpoint
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;static&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="s2"&gt;&amp;#34;www&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="c1"&gt;// Create a simple serverless function responding to GET
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/source&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&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 class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;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="c1"&gt;// Publish the URL so we can easily access our app
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So what&amp;rsquo;s happening here? This code creates a &lt;code&gt;cloud.API&lt;/code&gt; which exposes
an HTTP endpoint to the internet. It serves static content at the root
of the API from what&amp;rsquo;s in the &lt;code&gt;www&lt;/code&gt; folder on your local machine. And it
serves a REST API on &lt;code&gt;GET /source&lt;/code&gt; which runs the JavaScript callback to
return the JSON object &lt;code&gt;{name: “AWS”}&lt;/code&gt; (our serverless function).
Finally, it exports the URL where the HTTP API is exposed.&lt;/p&gt;
&lt;p&gt;Now just run &lt;code&gt;pulumi update&lt;/code&gt; to deploy the application. Before the app
deploys, you&amp;rsquo;ll get a preview of what will be deployed and you can
choose to go ahead with the full deployment. Pulumi figures out all of
the cloud resources needed to run the code above and prepares that for
deployment.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/building-your-first-serverless-app-using-only-javascript/image.png" alt="results"&gt;&lt;/p&gt;
&lt;p&gt;Once deployed, your application will run in the cloud. Use
&lt;code&gt;pulumi stack output url&lt;/code&gt; to get the URL where your app is running, and
open it up in your browser:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/building-your-first-serverless-app-using-only-javascript/stack-output.png" alt="stack output"&gt;&lt;/p&gt;
&lt;p&gt;With Pulumi, we&amp;rsquo;ve built a serverless JavaScript app in just a few lines of code.
This approach avoided significant amounts of configuration (YAML, or
point-and-click). Pulumi also supports containers (including
Kubernetes), managed services, infrastructure and everything else in
between that you might need for building cloud applications.
&lt;a href="https://www.pulumi.com/docs/get-started/"&gt;Get started with Pulumi&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="why-javascript-for-serverless-programming"&gt;Why JavaScript for serverless programming?&lt;/h2&gt;
&lt;p&gt;There are many great reasons to use JavaScript for serverless
programming (and cloud programming generally). Pulumi also supports
TypeScript, Python, and Go with more languages on the way.&lt;/p&gt;
&lt;p&gt;Pulumi uses NPM, Express, and supports modern JavaScript features like
async await, module etc. and so you can bring your JavaScript skills
directly to cloud programming.&lt;/p&gt;
&lt;h3 id="code-is-the-best-config"&gt;Code is the best Config&lt;/h3&gt;
&lt;p&gt;Serverless platforms such as AWS Lambda offer an easy and cost-effective
way to run your code in the cloud. But using these serverless platforms
often requires learning lots of finicky details of the cloud platform,
and using esoteric YAML configuration files to tell the cloud platform
how to run your app. Often, the work needed to configure the app can
outweigh the work needed to code the app.&lt;/p&gt;
&lt;p&gt;Pulumi changes that, and lets you create serverless
cloud applications using &lt;strong&gt;only&lt;/strong&gt; JavaScript (or TypeScript). These
applications can use all the features of cloud platforms like Amazon Web Services (AWS), Azure
or Google Cloud Platform (GCP) - but exposed as simple JavaScript APIs on NPM.&lt;/p&gt;
&lt;p&gt;This means that you can write code that contains logic alongside code
that defines the services and infrastructure needed to run it and Pulumi
can then deployed the app in seconds and run as a managed, scalable and -
in the case of serverless apps such as this one - extremely low cost
service on your chosen cloud.&lt;/p&gt;
&lt;h3 id="code-is-more-productive-expressive-and-fun"&gt;Code is more productive, expressive, and&amp;hellip; fun&lt;/h3&gt;
&lt;p&gt;One of the biggest advantages of a pure code approach is the automatic
gains from better tooling support. In particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Code completion.&lt;/strong&gt; There are a lot of services in each cloud.
Wouldn&amp;rsquo;t it be great to be able to autocomplete?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error checking.&lt;/strong&gt; Less worry about correctly indented YAML, more
real error checking.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versioning and Packaging.&lt;/strong&gt; Much improved versioning and packaging
scenarios through Github and NPM workflows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reusable components.&lt;/strong&gt; Build on top of base classes, and share for
easy reuse, standard configurations and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/uploads/content/blog/building-your-first-serverless-app-using-only-javascript/code-completion.gif" alt="code-completion"&gt;&lt;/p&gt;
&lt;h2 id="want-more"&gt;Want more?&lt;/h2&gt;
&lt;p&gt;To learn more take a look at more tutorials and example code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our origin story: &lt;a href="http://joeduffyblog.com/2018/06/18/hello-pulumi/"&gt;Hello, Pulumi!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tutorial: &lt;a href="https://www.pulumi.com/blog/deploying-production-ready-containers-with-pulumi/"&gt;Deploying Containers with Pulumi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tutorial: &lt;a href="https://www.pulumi.com/blog/build-a-video-thumbnailer-with-pulumi-using-lambdas-containers-and-infrastructure-on-aws/"&gt;Build a video thumbnailer using AWS Lambda, Fargate, and S3 in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/get-started/"&gt;Pulumi Quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slack.pulumi.com"&gt;Pulumi Community Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pulumi/examples"&gt;Pulumi Examples on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/languages-sdks/javascript/"&gt;Node.js and Pulumi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/blog/running-a-serverles-nodejs-http-server-on-aws-and-azure/"&gt;Node.js Examples for AWS and Azure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>Marc Holmes</author><category>serverless</category></item></channel></rss>