<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Serverless on Absolute Reason</title>
    <link>https://absolutereason.io/blog/tags/serverless/</link>
    <description>Recent content in Serverless on Absolute Reason</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <copyright>Copyright © 2026 Lone Mountain Research, LLC. All rights reserved.</copyright>
    <lastBuildDate>Sun, 19 Apr 2026 11:40:54 -0700</lastBuildDate>
    <atom:link href="https://absolutereason.io/blog/tags/serverless/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Computeless Servering</title>
      <link>https://absolutereason.io/blog/posts/computeless-servering/</link>
      <pubDate>Sun, 19 Apr 2026 11:40:54 -0700</pubDate>
      <guid>https://absolutereason.io/blog/posts/computeless-servering/</guid>
      <description>Unintended uses of cloud resources</description>
      <content:encoded><![CDATA[<p>Several years ago I was tinkering with <a href="https://aws.amazon.com/api-gateway/">AWS API Gateway</a> and reading through the documentation on the <a href="https://velocity.apache.org/engine/2.0/vtl-reference.html">Apache Velocity Template Language (VTL)</a> that is used for data transformations. I noticed that one of the <a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html">built-in variables</a> was <code>$context.identity.sourceIp</code> which contained the client&rsquo;s IP address.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> It occurred to me that I could make one of those &ldquo;what&rsquo;s my IP&rdquo; services by pointing the root of the API gateway at a <code>MOCK</code> integration with a response of type <code>text/plain</code> containing only that variable. No <a href="https://aws.amazon.com/lambda/">Lambda</a> function was needed. I tried it and it worked as expected. It has been running in one of my accounts for years and I use it in many of my build scripts (there isn&rsquo;t much point to this since AWS has their own at <a href="https://checkip.amazonaws.com/)">https://checkip.amazonaws.com/)</a>.</p>
<p>In <a href="https://www.hashicorp.com/en/products/terraform">Terraform</a> (or <a href="https://opentofu.org/">OpenTofu</a>), the relevant resources look like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-hcl" data-lang="hcl"><span style="display:flex;"><span><span style="color:#75715e"># Return caller IP as plain text via API Gateway (no backend)
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">resource</span> <span style="color:#e6db74">&#34;aws_api_gateway_rest_api&#34; &#34;ip&#34;</span> {
</span></span><span style="display:flex;"><span>  name        <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;ip&#34;</span>
</span></span><span style="display:flex;"><span>  description <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;My IP&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">endpoint_configuration</span> {
</span></span><span style="display:flex;"><span>    types <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;REGIONAL&#34;</span>]
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">resource</span> <span style="color:#e6db74">&#34;aws_api_gateway_method&#34; &#34;ip_method_get&#34;</span> {
</span></span><span style="display:flex;"><span>  rest_api_id   <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">id</span>
</span></span><span style="display:flex;"><span>  resource_id   <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">root_resource_id</span>
</span></span><span style="display:flex;"><span>  http_method   <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;GET&#34;</span>
</span></span><span style="display:flex;"><span>  authorization <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;NONE&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">resource</span> <span style="color:#e6db74">&#34;aws_api_gateway_integration&#34; &#34;ip_get_integration&#34;</span> {
</span></span><span style="display:flex;"><span>  rest_api_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">id</span>
</span></span><span style="display:flex;"><span>  resource_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">root_resource_id</span>
</span></span><span style="display:flex;"><span>  http_method <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_method</span>.<span style="color:#66d9ef">ip_method_get</span>.<span style="color:#66d9ef">http_method</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  type <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;MOCK&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  passthrough_behavior <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;WHEN_NO_MATCH&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  request_templates <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    &#34;application/json&#34;                  <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;{ \&#34;statusCode\&#34;: 200 }&#34;</span>
</span></span><span style="display:flex;"><span>    &#34;application/xml&#34;                   <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;{ \&#34;statusCode\&#34;: 200 }&#34;</span>
</span></span><span style="display:flex;"><span>    &#34;application/x-www-form-urlencoded&#34; <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;{ \&#34;statusCode\&#34;: 200 }&#34;</span>
</span></span><span style="display:flex;"><span>    &#34;text/plain&#34;                        <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;{ \&#34;statusCode\&#34;: 200 }&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">resource</span> <span style="color:#e6db74">&#34;aws_api_gateway_method_response&#34; &#34;ip_get_method_response_200&#34;</span> {
</span></span><span style="display:flex;"><span>  rest_api_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">id</span>
</span></span><span style="display:flex;"><span>  resource_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">root_resource_id</span>
</span></span><span style="display:flex;"><span>  http_method <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_method</span>.<span style="color:#66d9ef">ip_method_get</span>.<span style="color:#66d9ef">http_method</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  status_code <span style="color:#f92672">=</span> <span style="color:#ae81ff">200</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  response_models <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    &#34;text/plain&#34; <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Empty&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  response_parameters <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    &#34;method.response.header.Content-Type&#34; <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">resource</span> <span style="color:#e6db74">&#34;aws_api_gateway_integration_response&#34; &#34;ip_get_integration_response_200&#34;</span> {
</span></span><span style="display:flex;"><span>  rest_api_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">id</span>
</span></span><span style="display:flex;"><span>  resource_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_rest_api</span>.<span style="color:#66d9ef">ip</span>.<span style="color:#66d9ef">root_resource_id</span>
</span></span><span style="display:flex;"><span>  http_method <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_method</span>.<span style="color:#66d9ef">ip_method_get</span>.<span style="color:#66d9ef">http_method</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  status_code <span style="color:#f92672">=</span> <span style="color:#66d9ef">aws_api_gateway_method_response</span>.<span style="color:#66d9ef">ip_get_method_response_200</span>.<span style="color:#66d9ef">status_code</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  response_templates <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    &#34;text/plain&#34; <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;$context.identity.sourceIp\n&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  response_parameters <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    &#34;method.response.header.Content-Type&#34; <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#39;text/plain&#39;&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The IP example is trivial, but the underlying pattern is more broadly useful. API gateway’s mapping layer can read request metadata and generate responses without a backend. In the spirit of <em>serverless computing</em>, I called this <em>computeless servering</em>.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> There are probably a lot of opportunities to provide similarly trivial but useful services using only the intermediary building blocks in various cloud services.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>From the perspective of the gateway, not necessarily its real original IP address.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Yes, technically there is a compute layer. There are servers in <em>serverless computing</em> too.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
