<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vincent Van der Kussen, Author at Cloudar</title>
	<atom:link href="https://cloudar.be/author/vincent/feed/" rel="self" type="application/rss+xml" />
	<link>https://cloudar.be/author/vincent/</link>
	<description>100% Focus On AWS // 100% Customer Obsession</description>
	<lastBuildDate>Thu, 19 Apr 2018 08:30:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Connect to private resources from API Gateway with VPC Link</title>
		<link>https://cloudar.be/awsblog/connect-to-private-resources-from-api-gateway-with-vpc-link/</link>
					<comments>https://cloudar.be/awsblog/connect-to-private-resources-from-api-gateway-with-vpc-link/#comments</comments>
		
		<dc:creator><![CDATA[Vincent Van der Kussen]]></dc:creator>
		<pubDate>Thu, 19 Apr 2018 08:30:17 +0000</pubDate>
				<category><![CDATA[AWS Blog]]></category>
		<category><![CDATA[api gateway]]></category>
		<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://cloudar.be/?p=6099</guid>

					<description><![CDATA[<p>Until recently it was not possible to reach services in your VPC&#8217;s private subnets from API  Gateway. This recently changed and API Gateway now supports Endpoints to Private VPC&#8217;s . This means you can reach services in Private VPC&#8217;s without using custom headers or Lambda Proxy&#8217;s. In this example we will create an API in [&#8230;]</p>
<p>The post <a href="https://cloudar.be/awsblog/connect-to-private-resources-from-api-gateway-with-vpc-link/">Connect to private resources from API Gateway with VPC Link</a> appeared first on <a href="https://cloudar.be">Cloudar</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Until recently it was not possible to reach services in your VPC&#8217;s private subnets from API  Gateway. This recently changed and API Gateway now supports Endpoints to Private<br />
VPC&#8217;s . This means you can reach services in Private VPC&#8217;s without using custom headers or Lambda Proxy&#8217;s.</p>
<p>In this example we will create an API in API Gateway with some resources . When we access these resources, API Gateway will contact the backend which runs in a <strong>private subnet</strong> and returns the response back to the client.</p>
<p>The following endpoints will be created:</p>
<ul>
<li><strong>/</strong> (returns the status of the API)</li>
<li><strong>/header</strong> (returns the host header of the request)</li>
<li><strong>/foo/*</strong> (example to proxy everything under /foo to the backend)</li>
</ul>
<p>To establish this connection a <strong>Network Load Balancer</strong> (NLB) will be used. A <strong>Network Load Balancer</strong> operates at level 4 of the OSI model and therefore only uses the TCP protocol. We will use HTTP to communicate with our service In this example we use Nginx as a proxy to our application.</p>
<h2>Network Load Balancer</h2>
<p>Open the <strong>AWS EC2</strong> console and create a new <strong>Load Balancer</strong> of the type <strong>Network Load Balancer</strong></p>
<p><img fetchpriority="high" decoding="async" class="wp-image-6104 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/02.png" alt="" width="581" height="426" /></p>
<ul>
<li>Give it a name and choose <strong>Internal Facing</strong> (we don&#8217;t want to expose it publicly).</li>
<li>Select <strong>TCP</strong> and Choose port 80 (this is the tcp port where we will receive connections on).</li>
<li>In <strong>Availability Zones</strong> select the VPC and subnets where you want to deploy the NLB.</li>
</ul>
<h3><img decoding="async" class="alignnone wp-image-6108" src="https://cloudar.be/wp-content/uploads/2018/04/03.png" alt="" width="1016" height="664" srcset="https://cloudar.be/wp-content/uploads/2018/04/03.png 1272w, https://cloudar.be/wp-content/uploads/2018/04/03-768x502.png 768w, https://cloudar.be/wp-content/uploads/2018/04/03-1102x720.png 1102w" sizes="(max-width: 1016px) 100vw, 1016px" /></h3>
<h3>Configure routing</h3>
<p>In the next step we need to create a <strong>Target Group</strong> (or use an existing one). In this example we will create a new target group. In the Health Check configuration we&#8217;ll use the same port as the traffic port.</p>
<p><strong>NOTE</strong>:<em> If your backend service is listening on another tcp port you&#8217;ll need to adjust this so that the health check doesn&#8217;t fail.</em></p>
<h3><img decoding="async" class="size-full wp-image-6107 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/04.png" alt="" width="607" height="450" /></h3>
<h3>Register targets</h3>
<p>In the next screen select the instances where you want to send traffic to. You can also skip this and add the instances later.</p>
<p><strong><img loading="lazy" decoding="async" class="size-full wp-image-6109 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/05.png" alt="" width="1100" height="219" srcset="https://cloudar.be/wp-content/uploads/2018/04/05.png 1100w, https://cloudar.be/wp-content/uploads/2018/04/05-768x153.png 768w" sizes="auto, (max-width: 1100px) 100vw, 1100px" /></strong></p>
<p><strong>NOTE</strong>: <em>Instead of a single instance you could also attach the Target Group to an Auto Scaling Group.</em></p>
<h2>API Gateway</h2>
<p>Now that we have our NLB configured we can configure our <strong>API Gateway</strong>.</p>
<h3>Configure the VPC Link in API gateway</h3>
<p>Open the <strong>API Gateway</strong> console and choose<strong> VPC Links</strong>. Create a new <strong>VPC Link</strong> and select the <strong>Target NLB</strong> we created earlier.</p>
<h3>Create the API</h3>
<p>Now we can create our API. The fasted way is to create a Swagger file and import that.</p>
<p>Example Swagger file:</p>
<pre class="height-set:true lang:default decode:true" title="swagger.yml">{
  "swagger": "2.0",
  "info": {
    "version": "2017-11-17T04:40:23Z",
    "title": "MyAppAPI"
  },
  "host": "p3wocvip9a.execute-api.us-west-2.amazonaws.com",
  "basePath": "/",
  "schemes": [
    "https"
  ],
  "paths": {
    "/": {
      "get": {
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "http://flaskapp-api.vincent.cloudar.be",
          "passthroughBehavior": "when_no_match",
          "connectionType": "VPC_LINK",
          "connectionId": "${stageVariables.vpcLinkId}",
          "httpMethod": "GET",
          "type": "http_proxy"
        }
      }
    },
    "/header": {
      "get": {
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "http://flaskapp-api.vincent.cloudar.be/header",
          "passthroughBehavior": "when_no_match",
          "connectionType": "VPC_LINK",
          "connectionId": "${stageVariables.vpcLinkId}",
          "httpMethod": "GET",
          "type": "http_proxy"
        }
      }
    },
    "/foo/{proxy+}": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "http://flaskapp-api.vincent.cloudar.be/foo/{proxy}",
          "passthroughBehavior": "when_no_match",
          "connectionType": "VPC_LINK",
          "connectionId": "${stageVariables.vpcLinkId}",
          "httpMethod": "GET",
          "type": "http_proxy",
          "requestParameters": {
            "integration.request.path.proxy": "method.request.path.proxy"
          }
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
</pre>
<p>Once created you should see your API Resources</p>
<h3><img loading="lazy" decoding="async" class="size-full wp-image-6113 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/06.png" alt="" width="706" height="331" /></h3>
<h3>Create VPCLink</h3>
<p>To create the actual connection to our <strong>private subnets</strong> we need to create a <strong>VPC Link</strong>. In the API Gateway console and choose <strong>VPC Links</strong>. Create a new VPC Link and select the <strong>Target NLB</strong> we created earlier.</p>
<h3><img loading="lazy" decoding="async" class="size-full wp-image-6114 alignleft" src="https://cloudar.be/wp-content/uploads/2018/04/07.png" alt="" width="538" height="549" /><img loading="lazy" decoding="async" class="size-full wp-image-6115 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/08.png" alt="" width="565" height="329" /></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3>Deploy API</h3>
<p>We can now deploy the API by running<strong> APIs =&gt; &lt;your api name&gt; =&gt;</strong> <strong>Actions</strong> =&gt; <strong>Deploy API</strong> . Choose a name for the stage (in this example we use &#8216;test&#8217; ).</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-6116 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/09.png" alt="" width="629" height="415" /></p>
<p>Once deployed you will see a<strong> &#8216;test&#8217;</strong> stage under <strong>Stages</strong>. Navigate to the <strong>Stage Variables</strong> tab and add a new variable with the name <strong>vpcLinkId </strong> and the value is the ID of the VPCLink we created earlier.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-6117 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/10.png" alt="" width="1024" height="380" srcset="https://cloudar.be/wp-content/uploads/2018/04/10.png 1024w, https://cloudar.be/wp-content/uploads/2018/04/10-768x285.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>Create Custom Domainname</p>
<p>Because we are using Virtual Hosts in Nginx based on the incoming url we will have to make the API available on that URL. To do this we need to create a Custom Domain Name in the API Gateway Console.<br />
In this example we are using <em><strong>flaskapp-api.vincent.cloudar.be</strong></em></p>
<h3><img loading="lazy" decoding="async" class="size-full wp-image-6119 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/12.png" alt="" width="456" height="495" /><img loading="lazy" decoding="async" class="size-full wp-image-6121 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/131.png" alt="" width="450" height="353" /></h3>
<p><strong>NOTE</strong>: <em>Because Cloudfront is used for this, it can take a while until the Cloudfront Distribution is deployed.</em></p>
<p>We will also need to create a DNS record in <strong>Route 53 </strong>that will point to this Cloudfront Distribution. Use the <strong>Target Domain Name</strong> value.</p>
<h3><img loading="lazy" decoding="async" class="size-full wp-image-6123 alignnone" src="https://cloudar.be/wp-content/uploads/2018/04/141.png" alt="" width="414" height="491" /></h3>
<h3>Testing</h3>
<p>The backend application used in this example is a simple Python Flask application which exposes some API endpoints:</p>
<p><em>Python Flask app:</em></p>
<pre class="lang:python decode:true">#!/usr/bin/env python
# coding=utf-8
from flask import Flask, jsonify
from flask import request

app = Flask(__name__)

@app.route('/', methods=['GET'])
def get_health():
    return jsonify({'status': 'OK'})

@app.route('/header', methods=['GET'])
def get_header():
    header = request.headers['host']
    return jsonify({'header': header})

@app.route('/foo/bar', methods=['GET'])
def get_foobar():
    return jsonify({'foo': 'bar'})

@app.route('/foo/baz', methods=['GET'])
def get_foobaz():
    return jsonify({'foo': 'baz'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)
</pre>
<p>The application is proxied by Nginx.</p>
<p>NOTE: The <strong>server_name</strong> parameter is important as API Gateway will send the <strong>Endpoint URL</strong> configured in the <strong>Integration Request</strong> as host header.</p>
<p><em>Nginx config:</em></p>
<pre class="lang:default decode:true">server {
    listen      80;
    server_name flaskapp-api.vincent.cloudar.be;
    charset     utf-8;

    location / {
        include 	   uwsgi_params;
    	uwsgi_pass         127.0.0.1:8080;
    }
}
</pre>
<p>Now let&#8217;s see if everything works.</p>
<pre class="theme:solarized-dark lang:sh decode:true">[~] http &lt;strong&gt;https://flaskapp-api.vincent.cloudar.be/&lt;/strong&gt;                                                                                   7:32:02 
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 20
Content-Type: application/json
Date: Mon, 16 Apr 2018 05:32:06 GMT
Via: 1.1 f3a5b0b3f0604afcc0fb3447f930ad0a.cloudfront.net (CloudFront)
X-Amz-Cf-Id: zhRmMp-MCnNoCOy-sP5ry-CIChZvhvo5p81MzBp8_HPf67UoC33Teg==
X-Cache: Miss from cloudfront
x-amz-apigw-id: Fa1FdHapDoEF9mg=
x-amzn-Remapped-Connection: keep-alive
x-amzn-Remapped-Content-Length: 20
x-amzn-Remapped-Date: Mon, 16 Apr 2018 05:32:06 GMT
x-amzn-Remapped-Server: nginx/1.12.1
x-amzn-RequestId: 7ffddb48-4137-11e8-9f89-cd357aeb7d73

{
    "status": "OK"
}
</pre>
<p>&nbsp;</p>
<pre class="theme:solarized-dark lang:sh decode:true">[~] http &lt;strong&gt;https://flaskapp-api.vincent.cloudar.be/header&lt;/strong&gt;                                                                             7:32:06 
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 49
Content-Type: application/json
Date: Mon, 16 Apr 2018 05:33:42 GMT
Via: 1.1 777c0716c0ef8010208c3559195306d7.cloudfront.net (CloudFront)
X-Amz-Cf-Id: oIuKAnxpDyRN7h0wmTOfr5iXFFfrbypQRA7IaOR4_86dNtUf9OnxAg==
X-Cache: Miss from cloudfront
x-amz-apigw-id: Fa1UjEfYjoEFuGA=
x-amzn-Remapped-Connection: keep-alive
x-amzn-Remapped-Content-Length: 49
x-amzn-Remapped-Date: Mon, 16 Apr 2018 05:33:42 GMT
x-amzn-Remapped-Server: nginx/1.12.1
x-amzn-RequestId: b990526d-4137-11e8-bbf1-c7ecef1da020

{
    "header": "flaskapp-api.vincent.cloudar.be"
}
</pre>
<p>&nbsp;</p>
<pre class="theme:solarized-dark lang:sh decode:true">[~] http https://flaskapp-api.vincent.cloudar.be/foo/bar                                                                            7:33:42 
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 18
Content-Type: application/json
Date: Mon, 16 Apr 2018 05:34:06 GMT
Via: 1.1 a86da8347e06cd1a49dfa25142e0bbf8.cloudfront.net (CloudFront)
X-Amz-Cf-Id: HEAqrKKSqZnT2SVg7VUF8RINEJQp92sUiliTOyjCcm9JQOxlzoDdIw==
X-Cache: Miss from cloudfront
x-amz-apigw-id: Fa1YSGaojoEFYdA=
x-amzn-Remapped-Connection: keep-alive
x-amzn-Remapped-Content-Length: 18
x-amzn-Remapped-Date: Mon, 16 Apr 2018 05:34:06 GMT
x-amzn-Remapped-Server: nginx/1.12.1
x-amzn-RequestId: c7d93e62-4137-11e8-b8fa-852d561a1e18

{
    "foo": "bar"
}
</pre>
<h2>Conclusion</h2>
<p>If you want to use API Gateway but don&#8217;t want or can&#8217;t expose your backend services publicly VPC Link can be a good solution. However you&#8217;ll still need to find a solution to proxy the requests and do TLS/SSL offloading. Of course it will probably be a matter of time before AWS supports this natively.</p>
<p>&nbsp;</p>
<p>The post <a href="https://cloudar.be/awsblog/connect-to-private-resources-from-api-gateway-with-vpc-link/">Connect to private resources from API Gateway with VPC Link</a> appeared first on <a href="https://cloudar.be">Cloudar</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://cloudar.be/awsblog/connect-to-private-resources-from-api-gateway-with-vpc-link/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
