<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Cloud.gov Docs Blog</title>
        <link>https://docs.cloud.gov/knowledge-base/</link>
        <description>Cloud.gov Docs Blog</description>
        <lastBuildDate>Wed, 17 Sep 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Endpoint Agents on Cloud.gov PaaS]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/</guid>
            <pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Why OS-level endpoint agents cannot be installed in Cloud.gov PaaS, what protections you inherit, and what you can do instead.]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><ul>
<li class="">OS-level endpoint detection and response (EDR) agents <strong>cannot</strong> be installed in Cloud.gov PaaS.</li>
<li class="">Cloud.gov operates under a <strong>FedRAMP Moderate Authorization (package ID F1607067912)</strong>. You inherit infrastructure and platform-level protections.</li>
<li class=""><strong>Customer Responsibility:</strong> Secure your applications, dependencies, logs, and integrate them into your own monitoring processes.</li>
</ul></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="overview">Overview<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#overview" class="hash-link" aria-label="Direct link to Overview" title="Direct link to Overview" translate="no">​</a></h2>
<p>Cloud.gov is a <strong>Platform as a Service (PaaS)</strong>. You deploy <strong>applications</strong>, while Cloud.gov operates and secures the <strong>underlying platform</strong> (hosts, containers, networking, orchestration).<br>
<!-- -->Because customers do not have access to operating systems or container hosts in a PaaS model, <strong>OS-level endpoint agents cannot be installed</strong>. This design ensures consistency, security, and compliance across all tenants.</p>
<p><strong>Customer Responsibility:</strong> Secure your <strong>application layer</strong>—this includes code, dependencies, data flows, logs/metrics, CI/CD security, and application incident response.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="shared-responsibility-at-a-glance">Shared Responsibility at a Glance<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#shared-responsibility-at-a-glance" class="hash-link" aria-label="Direct link to Shared Responsibility at a Glance" title="Direct link to Shared Responsibility at a Glance" translate="no">​</a></h2>
<!-- -->
<p><strong>Accessibility Note:</strong> The diagram shows that Cloud.gov manages infrastructure, operating systems, containers, networking, and platform monitoring. Customers manage application code, dependencies, logs, and testing. Endpoint agents are <strong>not permitted</strong> at the platform layer.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-you-can-do-instead">What You Can Do Instead<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#what-you-can-do-instead" class="hash-link" aria-label="Direct link to What You Can Do Instead" title="Direct link to What You Can Do Instead" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="immediate-actions">Immediate Actions<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#immediate-actions" class="hash-link" aria-label="Direct link to Immediate Actions" title="Direct link to Immediate Actions" translate="no">​</a></h3>
<ul>
<li class=""><strong>Forward app logs/metrics</strong> to your SIEM or monitoring system using supported interfaces.</li>
<li class=""><strong>Instrument CI/CD pipelines</strong> with static, dynamic, and interactive security testing (SAST/DAST/IAST).</li>
<li class=""><strong>Generate and maintain a Software Bill of Materials (SBOM)</strong> for all builds; alert on changes to critical components.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="best-practices">Best Practices<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#best-practices" class="hash-link" aria-label="Direct link to Best Practices" title="Direct link to Best Practices" translate="no">​</a></h3>
<ul>
<li class=""><strong>Use in-process protections</strong> (e.g., runtime application self-protection libraries) within your app if compatible.</li>
<li class=""><strong>Leverage threat intel and APIs</strong> for enrichment and detections at the application layer.</li>
<li class=""><strong>Adopt provenance and artifact signing</strong> (e.g., SLSA-aligned pipelines) for supply-chain security.</li>
<li class=""><strong>Develop and test an app-focused incident response plan</strong> that aligns with your agency’s processes.</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="faqs">FAQs<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#faqs" class="hash-link" aria-label="Direct link to FAQs" title="Direct link to FAQs" translate="no">​</a></h2>
<p><strong>Q: Why can’t I install an endpoint agent?</strong>
Because PaaS boundaries prevent OS or kernel access. This is fundamental to Cloud.gov’s multi-tenant security model.</p>
<p><strong>Q: Do we still get malware and threat monitoring?</strong>
Yes—at the <strong>platform</strong> layer, operated by Cloud.gov. You are responsible for monitoring at the <strong>application</strong> layer.</p>
<p><strong>Q: Could we run a sidecar container with an endpoint agent?</strong>
If it requires host/privileged access or kernel hooks: <strong>No</strong>. If it operates purely at the app layer, evaluate it like any other dependency.</p>
<p><strong>Q: Can we use EDR data without an agent?</strong>
Yes. You can forward application logs, integrate APIs, and apply policies in your CI/CD pipelines.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="roles--responsibilities">Roles &amp; Responsibilities<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#roles--responsibilities" class="hash-link" aria-label="Direct link to Roles &amp; Responsibilities" title="Direct link to Roles &amp; Responsibilities" translate="no">​</a></h2>
<ul>
<li class=""><strong>Cloud.gov (Inherited):</strong> Host OS hardening, container runtime, network controls, platform monitoring &amp; incident response.</li>
<li class=""><strong>Customer Responsibility:</strong> Application code/configuration, dependencies &amp; SBOM, CI/CD security testing, app logs/metrics, and application-layer incident response.</li>
</ul>
<p><strong>Customer Responsibility:</strong> Ensure your System Security Plan (SSP) reflects <strong>inherited vs. shared vs. customer-owned</strong> controls accurately, using the FedRAMP Control Responsibility Matrix (CRM) as a guide.</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="compliance-context">Compliance Context<a href="https://docs.cloud.gov/knowledge-base/2025/09/17/endpoint-agents-on-cloudgov-paas/#compliance-context" class="hash-link" aria-label="Direct link to Compliance Context" title="Direct link to Compliance Context" translate="no">​</a></h2>
<p>Cloud.gov operates under a <strong>FedRAMP Moderate Authorization (package ID F1607067912)</strong>. Customers inherit platform-level controls. You must implement and document application-level security controls in accordance with NIST SP 800-53 Rev 5 and the FedRAMP CRM.</p>
<hr>
<p>If you have any additional questions, please contact <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a> and we would be happy to assist you.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Monitoring your application's health using OpenSearch]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2025/03/27/monitoring-app-metrics-opensearch/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2025/03/27/monitoring-app-metrics-opensearch/</guid>
            <pubDate>Thu, 27 Mar 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[One of the benefits of hosting your applications on Cloud.gov is that it offers performance metrics for monitoring the health of your application.]]></description>
            <content:encoded><![CDATA[<p>One of the benefits of hosting your applications on Cloud.gov is that it offers <a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html#container-metrics" target="_blank" rel="noopener noreferrer" class="">performance metrics for monitoring the health of your application</a>.</p>
<p>The most important metrics for monitoring your application's health are the memory and CPU metrics, which can help you identify:</p>
<ul>
<li class="">If your application has enough memory provisioned per instance</li>
<li class="">If your application is experiencing CPU spikes and associated performance issues</li>
<li class="">If you need <a class="" href="https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/">to horizontally scale your application instances</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-note-about-cpu-metrics">A note about CPU metrics<a href="https://docs.cloud.gov/knowledge-base/2025/03/27/monitoring-app-metrics-opensearch/#a-note-about-cpu-metrics" class="hash-link" aria-label="Direct link to A note about CPU metrics" title="Direct link to A note about CPU metrics" translate="no">​</a></h2>
<p>Your application runs in one or more application containers distributed across Diego cell virtual machines (VMs). CPUs are virtualized and shared with other application containers on the VM.</p>
<p><a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html#container-metrics" target="_blank" rel="noopener noreferrer" class="">The CPU usage figure reported as part of the application metrics represents the CPU usage of an application instance as a percentage of a single CPU core</a>. Since there are usually multiple CPU cores per VM, <strong>it is possible for the CPU usage to exceed 100%</strong>, which means your application is using the equivalent compute power of more than a single CPU core.</p>
<p>A CPU usage figure above 100% is not necessarily problematic. The more important metric for identifying issues is CPU entitlement, which is <a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html#container-metrics" target="_blank" rel="noopener noreferrer" class="">a formula Cloud Foundry uses to determine how much CPU your application <strong>is allowed to use</strong> from the host VM based on its memory capacity</a>.</p>
<p>If the CPU entitlement figure exceeds 100% for any application instance, then the instance is effectively borrowing spare CPU resources from the host VM. Since applications are regularly redistributed across the available host VMs, the amount of spare CPU capacity available on the VM can change, so any instances of CPU entitlement above 100% should be treated as an indication of insufficient application resources and addressed appropriately by adding more instances or allocating more memory.</p>
<p>While the CPU usage figure itself does not independently reveal application issues, it is still worth monitoring as a relative value, since sudden spikes in the value can still indicate abnormal performance of your application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="retrieving-current-memory-and-cpu-metrics">Retrieving current memory and CPU metrics<a href="https://docs.cloud.gov/knowledge-base/2025/03/27/monitoring-app-metrics-opensearch/#retrieving-current-memory-and-cpu-metrics" class="hash-link" aria-label="Direct link to Retrieving current memory and CPU metrics" title="Direct link to Retrieving current memory and CPU metrics" translate="no">​</a></h2>
<p>To retrieve the current memory, CPU usage and CPU entitlement for your app, you can use the <code>cf app</code> command:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf app APP-NAME</span><br></span></code></pre></div></div>
<p>The output from running that command will look something like:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of application summary printed in a terminal session by the cf app command&amp;quot;" src="https://docs.cloud.gov/assets/images/cf-app-metrics2-a42cd832d234d64e0d949f81c0c187a4.png" width="1366" height="462" class="img_ev3q"></p>
<p>The <code>cpu</code> and <code>memory</code> metrics in the output can be interpreted as follows:</p>
<ul>
<li class=""><code>cpu</code>: percentage of CPU used by the application, as explained above.</li>
<li class=""><code>memory</code>: memory used out of the amount of memory allowed for each application instance.</li>
<li class=""><code>cpu entitlement</code>: CPU time used by an app instance as a percentage of its CPU entitlement.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-view-historical-memory-and-cpu-metrics-in-opensearch">How to view historical memory and CPU metrics in OpenSearch<a href="https://docs.cloud.gov/knowledge-base/2025/03/27/monitoring-app-metrics-opensearch/#how-to-view-historical-memory-and-cpu-metrics-in-opensearch" class="hash-link" aria-label="Direct link to How to view historical memory and CPU metrics in OpenSearch" title="Direct link to How to view historical memory and CPU metrics in OpenSearch" translate="no">​</a></h2>
<p>While it is useful to view your application's CPU and memory usage at a given point in time, what is usually
more helpful is to see the trends in your application's health metrics over time and in particular whether
they correlate to observed performance issues for your application.</p>
<p>Logs containing these application metrics are already ingested into the <a href="https://logs.fr.cloud.gov/" target="_blank" rel="noopener noreferrer" class="">OpenSearch instance for customer logs</a>. Furthermore, there are already built-in visualizations and dashboards for viewing these metrics for your applications.</p>
<p>To view the dashboards for application metrics, follow these steps:</p>
<ol>
<li class="">
<p>Log in to <a href="https://logs.fr.cloud.gov/" target="_blank" rel="noopener noreferrer" class="">OpenSearch</a>.</p>
</li>
<li class="">
<p>Click <code>Dashboard</code> in the bookmark links at the top of the page.
<img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of OpenSearch interface with an arrow pointing towards the Dashboard bookmark at the top of the page&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-click-dashboard-link-ff7f51a38722f40375f85c5872bfddec.png" width="1706" height="304" class="img_ev3q"></p>
</li>
<li class="">
<p>Enter <code>App - Metrics</code> in the search bar on the Dashboards page and click the link to the <code>App - Metrics</code> dashboard in the results.
<img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of OpenSearch dashboards search page with App - Metrics as the search query&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-search-app-metrics-dashboard-bbb8a0c2e68d50d7ffc028ea308bb979.png" width="2522" height="734" class="img_ev3q"></p>
</li>
<li class="">
<p>The <code>App - Metrics</code> dashboard should automatically populate with metrics for a graph of CPU usage, memory usage (in bytes), and disk usage for all of your applications. Add filters (e.g. <code>@cf.space</code>) to limit the results to the desired applications and adjust the time filter to see metrics for the desired time period.
<img decoding="async" loading="lazy" alt="&amp;quot;Full-page screenshot of the App - Metrics dashboard in OpenSearch displaying visualizations of CPU usage, memory usage, and disk usage based on application metrics&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-app-metrics-dashboard-44286423f9ef0222871fe6f583eefcd3.png" width="2878" height="1638" class="img_ev3q"></p>
</li>
</ol>
<p>If you encounter any difficulties using these dashboards or have any questions about them, please contact <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a> and we would be happy to assist you.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding OpenSearch Dashboards, logging and how to visualize your application logs]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/</guid>
            <pubDate>Tue, 10 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[What does Dashboards do?]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-does-dashboards-do">What does Dashboards do?<a href="https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/#what-does-dashboards-do" class="hash-link" aria-label="Direct link to What does Dashboards do?" title="Direct link to What does Dashboards do?" translate="no">​</a></h2>
<p>Dashboards is a user interface that lets you search and visualize your application logs. Dashboards has a <a href="https://opensearch.org/docs/latest/dashboards/" target="_blank" rel="noopener noreferrer" class="">user guide</a> that explains more about how to use it and to create custom visualizations.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-are-some-types-of-logs">What are some types of logs?<a href="https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/#what-are-some-types-of-logs" class="hash-link" aria-label="Direct link to What are some types of logs?" title="Direct link to What are some types of logs?" translate="no">​</a></h2>
<p>Cloud Foundry assigns a type to each log message depending on its origin. Application logs are assigned the APP log type. HTTP requests being routed to an app will produce the RTR log type. The various types of logs <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/streaming-logs.html#format" target="_blank" rel="noopener noreferrer" class="">are listed in the CloudFoundry documentation</a>.</p>
<p>The log type is stored on logs in the <code>@source.type</code> field. So to query for application logs, you could use a filter of <code>@source.type: "APP"</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="querying-logs">Querying Logs<a href="https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/#querying-logs" class="hash-link" aria-label="Direct link to Querying Logs" title="Direct link to Querying Logs" translate="no">​</a></h2>
<p>Cloud Foundry logs have a few useful fields which will be helpful for querying logs.
Cloud Foundry has 3 fields that can be very helpful to filter down what app logs show up.</p>
<ul>
<li class=""><code>@cf.org</code> - The organization, this is applicable to multi-org users</li>
<li class=""><code>@cf.space</code> - The space in a organization.</li>
<li class=""><code>@cf.app</code> - The app in a space.</li>
</ul>
<p>Other fields that may be useful for querying:</p>
<ul>
<li class=""><code>@message</code> - the app specific message attached to the log. This field supports full-text searching, so you can do a search of <code>@message: "foo"</code> to find all logs where <code>@message</code> contains <code>foo</code>.</li>
<li class=""><code>@raw</code> - the raw message received by OpenSearch before parsing into other fields. This field also supports full-text searching</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-visualize-application-traffic">How to visualize application traffic<a href="https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/#how-to-visualize-application-traffic" class="hash-link" aria-label="Direct link to How to visualize application traffic" title="Direct link to How to visualize application traffic" translate="no">​</a></h2>
<p>Router log data can be used to create a visualization of your application traffic following the steps below.</p>
<p>After you have logged into Dashboards, click "Discover" in the left sidebar menu. Then, add filters(under search bar) and search terms to query for router logs as seen in the screenshot below. Please note that the filters shown here for a specific space and application are just an example. You might want to view logs for all requests to application in a given space, in which case you would not want a filter for <code>@cf.app</code>.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Dashboard interface showing a query for router logs for a given CloudFoundry space and application&amp;quot;" src="https://docs.cloud.gov/assets/images/dashboard-router-55b39b49079cbab73ee3f33b03c6404e.png" width="2880" height="1054" class="img_ev3q"></p>
<p>The next step is to visualize your search results based on a specific field. To visualize request logs over time, choose the <code>@timestamp</code> field from the left sidebar of "Available fields". Then, click "Visualize".</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Dashboards interface showing the selection of @timestamp as field to use for visualizing request logs&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-timestamp-f836b73ed6de490a6577b9604a735926.png" width="1000" height="1502" class="img_ev3q"></p>
<p>By default, visualizing logs based on <code>@timestamp</code> will produce a histogram chart. To change the chart type to line, which might be more useful for this type of data, click the "Metrics &amp; axes" link in the chart configuration panel on the right side of the screen. Then, under "Metrics" and "Count", select "Line" from the "Chart type" drop-down. Finally, click the "Update" button at the bottom right of the screen and the chart should update to a line chart.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Dashboards visualization interface showing a line chart of requests over time with a panel for chart configuration options visible on the right side of the screen. In the chart configuration options, &amp;quot;line&amp;quot; is selected as the chart type&amp;quot;" src="https://docs.cloud.gov/assets/images/dashboard-line-0738a098ef3ab7913712fea83529152f.png" width="2168" height="1382" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fields-for-router-requests">Fields for router requests<a href="https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/#fields-for-router-requests" class="hash-link" aria-label="Direct link to Fields for router requests" title="Direct link to Fields for router requests" translate="no">​</a></h2>
<p>Listed below are the explanations of some field names for router (RTR) logs:</p>
<ul>
<li class=""><strong>rtr.app.id</strong>: The application guid</li>
<li class=""><strong>rtr.hostname</strong>: The domain/hostname the request was sent to (e.g&nbsp;test.app.cloud.gov)</li>
<li class=""><strong>rtr.http_user_agent</strong>: What user agent the request came from (Chrome, Firefox, Curl, etc…)</li>
<li class=""><strong>rtr.path</strong>: The specific url path that was requested (e.g. /my/test/page)</li>
<li class=""><strong>rtr.status</strong>: Gives the status of the request (200, 404, etc…)</li>
<li class=""><strong>rtr.verb</strong>: The type of request (POST, GET, etc...)</li>
<li class=""><strong>rtr.x_forwarded_for</strong>: The IP address the request came from</li>
<li class=""><strong>rtr.timestamp</strong>: The time of the request in UTC</li>
</ul>
<p>The full list of fields available for router logs can be found in <a href="https://github.com/cloud-gov/opensearch-boshrelease/blob/2078ff06dec204c12bc64a45fe707f71e1c9e303/jobs/opensearch_templates/templates/component-index-mappings-app.json.erb#L46" target="_blank" rel="noopener noreferrer" class="">our OpenSearch field mapping configuration</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="generate-report-of-logs">Generate report of logs<a href="https://docs.cloud.gov/knowledge-base/2024/12/10/using-opensearch-dashboards/#generate-report-of-logs" class="hash-link" aria-label="Direct link to Generate report of logs" title="Direct link to Generate report of logs" translate="no">​</a></h2>
<p>OpenSearch allows for <a href="https://opensearch.org/docs/latest/reporting/report-dashboard-index/" target="_blank" rel="noopener noreferrer" class="">generating a report</a> from a saved search. This is done by choosing a search and clicking the <strong>Reporting</strong> menu option.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Dashboards interface showing the selection of @timestamp as field to use for visualizing request logs&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-timestamp-f836b73ed6de490a6577b9604a735926.png" width="1000" height="1502" class="img_ev3q"></p>
<p><strong>Reports have a non-configurable 10,000 row limit</strong>. They have no explicit size limit (for example, MB),
but extremely large documents could cause report generation to fail</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Potential buildpack cache issue with apt-buildpack]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/12/09/apt-buildpack-cache-issue/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/12/09/apt-buildpack-cache-issue/</guid>
            <pubDate>Mon, 09 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[What does the buildpack cache do?]]></description>
            <content:encoded><![CDATA[<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-does-the-buildpack-cache-do">What does the buildpack cache do?<a href="https://docs.cloud.gov/knowledge-base/2024/12/09/apt-buildpack-cache-issue/#what-does-the-buildpack-cache-do" class="hash-link" aria-label="Direct link to What does the buildpack cache do?" title="Direct link to What does the buildpack cache do?" translate="no">​</a></h3>
<p>The buildpack cache (aka "app cache," or "build artifacts cache") is a per-application cache that is stored in the blob (binary large object) store and recovered when an existing application is restaged (regardless of application code or buildpack changes).</p>
<p>Different buildpacks use this cache for different things. <a class="" href="https://docs.cloud.gov/platform/deployment/frameworks/#supported-languages-and-frameworks">System buildpacks</a> are cached on the VM hosting the application container and then mounted as read-only volumes into each staging container. If your application references a custom buildpack or buildpack version via a URLs (to a git repo or a zip file), those buildpacks are downloaded every time application staging occurs.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="potential-cache-issue-with-apt-buildpack">Potential cache issue with apt-buildpack<a href="https://docs.cloud.gov/knowledge-base/2024/12/09/apt-buildpack-cache-issue/#potential-cache-issue-with-apt-buildpack" class="hash-link" aria-label="Direct link to Potential cache issue with apt-buildpack" title="Direct link to Potential cache issue with apt-buildpack" translate="no">​</a></h3>
<p>The potential issue with the <code>apt-buildpack</code> cache involves the&nbsp;<code>/</code>&nbsp;directory disk allocation. The <code>apt-buildpack</code> uses <code>/tmp</code> for its cache like other buildpacks. In all buildpacks, the&nbsp;<code>/</code>&nbsp;directory is allocated approximately 9% of the disk allocation, meaning that the size of the <code>/tmp</code> subdirectory cannot exceed that disk allocation. For most buildpacks, this disk allocation is sufficient as all the possible packages that they could be installing is known with the only variable being the application code. However, the <code>apt-buildpack</code> can install an unknown number of packages of variable size, such as the AWS CLI. Depending on how many packages are installed and their individual size, the allotted 9% of disk space may not be sufficient, causing application staging to fail with an error like:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">stdout: No space left on device. /usr/bin/tar: /tmp/output-cache: Wrote only 2048 of 10240 bytes</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-address-the-issue">How to address the issue<a href="https://docs.cloud.gov/knowledge-base/2024/12/09/apt-buildpack-cache-issue/#how-to-address-the-issue" class="hash-link" aria-label="Direct link to How to address the issue" title="Direct link to How to address the issue" translate="no">​</a></h3>
<p>If the number of packages that you are installing during staging is within the allotted 9% of the disk limit (2 GB default) you can attempt to resolve the issue by clearing the buildpack cache and attempting to push your application again. Please refer to the commands below to clear your buildpack cache.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">app_guid=$(cf app --guid &lt;staging-app-name&gt;)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cf curl -X POST /v3/apps/${app_guid}/actions/clear_buildpack_cache</span><br></span></code></pre></div></div>
<p>You can additionally configure the apt buildpack cache to purge any cached content by setting <code>cleancache</code> to true which calls <code>apt-get clean</code> and <code>apt-get autoclean</code> and is useful to remove any cached content per the apt buildpack <a href="https://github.com/cloudfoundry/apt-buildpack?tab=readme-ov-file#cloud-foundry-experimental-apt-buildpack" target="_blank" rel="noopener noreferrer" class="">documentation</a>.</p>
<p>If you encounter any difficulties deploying this solution or have any questions, please contact
<a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a> and we would be happy to assist you.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migrating to the OpenSearch Dashboard for Cloud.gov logs]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/</guid>
            <pubDate>Fri, 06 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[What's Changing in December 2024]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-changing-in-december-2024">What's Changing in December 2024<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#whats-changing-in-december-2024" class="hash-link" aria-label="Direct link to What's Changing in December 2024" title="Direct link to What's Changing in December 2024" translate="no">​</a></h2>
<p>As we <a href="https://cloud.gov/2024/11/21/new-logging-system/" target="_blank" rel="noopener noreferrer" class="">announced on November 21, 2024</a>, we are upgrading the Cloud.gov customer application logging system and the user interface at <a href="https://logs.fr.cloud.gov/" target="_blank" rel="noopener noreferrer" class="">https://logs.fr.cloud.gov</a>. The application logs interface prior to December 2024 was based on <a href="https://www.elastic.co/kibana" target="_blank" rel="noopener noreferrer" class=""><em>Kibana</em></a>, and we are migrating to one
based on <a href="https://www.opensearch.org/docs/latest/dashboards/" target="_blank" rel="noopener noreferrer" class=""><em>OpenSearch Dashboards</em></a>.</p>
<p>While all the underlying functionality is unchanged, or improved, there are some differences between Kibana (old) and OpenSearch (new), which we'll outline here.</p>
<p><strong>Note: You will need to <a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#migrating-kibana-customizations-to-opensearch" class="">migrate your saved objects</a></strong> (searches, visualizations) from Kibana to OpenSearch before January 7, 2025. After that date, importing objects will require a support request.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="logging-in-to-the-new-system">Logging in to the new system<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#logging-in-to-the-new-system" class="hash-link" aria-label="Direct link to Logging in to the new system" title="Direct link to Logging in to the new system" translate="no">​</a></h2>
<p>The first time you log in to the OpenSearch-based system you'll be presented
with the following OpenId "Application Authorization" dialog:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of dialog box titled Application Authorization: opensearch_dashboards_proxy with boxes checked for Access profile, View details of your applications and services and Read all SCIM entries. The options are Authorize or Deny&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-app-auth-dialog-c5b332e4ac2ebfe5dc3d10fb5de3d43d.png" width="455" height="666" class="img_ev3q"></p>
<p>You'll need to accept all the scopes. If for some reason you need to revoke
access later, you can do so at: <a href="https://login.fr.cloud.gov/profile" target="_blank" rel="noopener noreferrer" class="">https://login.fr.cloud.gov/profile</a></p>
<p>You'll then need to choose the Cloud.gov org you want to work with in the "Select you Tenant" dialog:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of dialog box titled Select your tenant&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch_select_tenant-6e612e27e7a8692b1ca50882aa6aad56.png" width="731" height="612" class="img_ev3q"></p>
<p>If you have access to multiple orgs, you can switch your tenant later by clicking the OpenSearch user avatar on top right.</p>
<p>The main OpenSearch Dashboard should resemble the Kibana dashboard. If you're provided a
Dashboard selection screen (see below), choose "App - Overview".</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of dialog box titled Dashboards&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch_choose_dashboard-fe7537c6b6e6fadc001521a6783f9787.png" width="850" height="673" class="img_ev3q"></p>
<p>Otherwise the main navigation menus should be familiar and you're now ready to explore your Cloud.gov logs with OpenSearch.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="migrating-kibana-customizations-to-opensearch">Migrating Kibana customizations to OpenSearch<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#migrating-kibana-customizations-to-opensearch" class="hash-link" aria-label="Direct link to Migrating Kibana customizations to OpenSearch" title="Direct link to Migrating Kibana customizations to OpenSearch" translate="no">​</a></h2>
<p>All of the application and CloudFoundry logs that have been available in Kibana
will be available to you in OpenSearch. You needn't take any action to ensure that.
You will need to migrate custom dashboards and saved searches by exporting them
from Kibana and importing them into OpenSearch.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="export-saved-objects-from-kibana">Export Saved Objects from Kibana<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#export-saved-objects-from-kibana" class="hash-link" aria-label="Direct link to Export Saved Objects from Kibana" title="Direct link to Export Saved Objects from Kibana" translate="no">​</a></h3>
<p>In Kibana, use the left navigation menu to select "Management" -&gt; "Stack Management":</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Kibana leftnav with Stack Management highlighted&amp;quot;" src="https://docs.cloud.gov/assets/images/kibana_select_stack_mgmt-38097423926339d084086a48f9cb79db.png" width="852" height="933" class="img_ev3q"></p>
<p>Then in the Stack Management view, select "Saved Objects" under the "Kibana" heading:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Kibana Stack Management with Saved Objects highlighted&amp;quot;" src="https://docs.cloud.gov/assets/images/kibana_select_saved_objects-7b61e613d51902571c5ba5a227fedd00.png" width="936" height="850" class="img_ev3q"></p>
<p>From the Saved Objects screen, you can search for the visualizations or
searches you've previously saved. From that screen you can export all the matching objects as a single <code>export.ndjson</code> file (as shown below),
or as individual <code>.ndjson</code> files:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Kibana View Saved Objects with Export 7 Objects highlighted&amp;quot;" src="https://docs.cloud.gov/assets/images/kibana_view_saved_objects-b2e7c93ca480ca37b0c2ed55ef12bb42.png" width="922" height="644" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="importing-saved-objects-into-opensearch">Importing saved objects into OpenSearch<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#importing-saved-objects-into-opensearch" class="hash-link" aria-label="Direct link to Importing saved objects into OpenSearch" title="Direct link to Importing saved objects into OpenSearch" translate="no">​</a></h3>
<p><strong>If you used the same saved object in Kibana across multiple Cloud.gov orgs</strong>,
you will need to import it into each OpenSearch tenant (each tenant corresponds to a Cloud.gov Cloud Foundry "org").</p>
<p>Once you've exported the objects as <code>.ndjson</code> files, switch to OpenSearch, then:</p>
<ul>
<li class="">From the LeftNav menu, select, "Management -&gt; Dashboards Management".</li>
<li class="">On the "Dashboards Management" window, select "Saved Objects" on the left menu.</li>
<li class="">Then select "Import" on the upper right corner.</li>
<li class="">On the "Import saved objects" window:<!-- -->
<ul>
<li class="">Select the file to upload</li>
<li class="">For "Import options" select:<!-- -->
<ul>
<li class="">"Check for existing objects"</li>
<li class="">"Request action on conflict"</li>
</ul>
</li>
<li class="">The click the "Import" button, as show below: <img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Import saved objects, with selections as described&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-import-saved-objects-db65da5fea1e55defa81d1bed9665802.png" width="760" height="1226" class="img_ev3q"></li>
<li class="">If the import results in an "Overwrite index-pattern" dialog, you will likely want to "Skip" the overwrite: <img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Overwrite index-pattern with Skip selected&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-import-overwrite-dialog-ce21ffe86b945a293dd0636f39954805.png" width="838" height="386" class="img_ev3q"></li>
<li class="">When the import is complete, click "Done"</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="recovering-saved-searches-and-visualizations-after-kibana-decomissioning">Recovering Saved Searches and Visualizations after Kibana decomissioning<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#recovering-saved-searches-and-visualizations-after-kibana-decomissioning" class="hash-link" aria-label="Direct link to Recovering Saved Searches and Visualizations after Kibana decomissioning" title="Direct link to Recovering Saved Searches and Visualizations after Kibana decomissioning" translate="no">​</a></h3>
<p>If you missed migrating a Saved Object
from Kibana to OpenSearch, and Kibana is no longer available,
please contact <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a>.
We have saved all customer objects and can recover those for you.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="user-interface-changes">User interface changes<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#user-interface-changes" class="hash-link" aria-label="Direct link to User interface changes" title="Direct link to User interface changes" translate="no">​</a></h2>
<p>The screenshot below show some of the major changes to the user interfaces, such as:</p>
<ol>
<li class="">The drop down menus have moved from the upper left to the upper right.</li>
<li class="">The "Top 5 values" for a field view is now an option to the right of the field, instead of a double-click.</li>
<li class="">There are a lot more values gathered for container metrics (see below) so you may notice a higher message count in OpenSearch.</li>
</ol>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot comparing Kibana to OpenSearch&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-ui-differences-48b5b387ecbf97194bcb1a752d88fce1.png" width="1273" height="1334" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-system-differences">Key system differences<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#key-system-differences" class="hash-link" aria-label="Direct link to Key system differences" title="Direct link to Key system differences" translate="no">​</a></h2>
<p>The Cloud.gov team has implemented OpenSearch to deliver a number of benefits to our customers. Among these are:</p>
<ul>
<li class="">Twelve months of live access to system logs, in alignment with <a href="https://www.whitehouse.gov/wp-content/uploads/2021/08/M-21-31-Improving-the-Federal-Governments-Investigative-and-Remediation-Capabilities-Related-to-Cybersecurity-Incidents.pdf" target="_blank" rel="noopener noreferrer" class="">M-21-31</a>.</li>
<li class="">Definitions of saved searches and visualizations are now isolated by OpenSearch tenants that correspond to Cloud.gov organizations.<!-- -->
<ul>
<li class="">You no longer need to worry about choosing a globally unique name.</li>
<li class="">If you share the same saved object across multiple orgs, you will need to import it into each of your orgs.</li>
</ul>
</li>
<li class="">Better handling of large log messages. Both Kibana/ELK and OpenSearch have a 32kb limit on message size. The older system dropped such messages from Kibana (although they were still retained in cold storage), the newer system, for JSON messages, keeps the first 32kb and discards the rest<!-- -->
<ul>
<li class="">Truncated messages are tagged with <code>_messagetrimmed</code>.</li>
<li class="">Extremely large log messages (over 1Mb) are trimmed and tagged <code>_logtrimmed</code> -- such message are probably indicative of a coding error in your application.</li>
<li class="">You can search for such messages with a filter of <code>@logs is one of "_messagetrimmed", "_logtrimmed"</code>, as shown here
<img decoding="async" loading="lazy" alt="&amp;quot;Screenshot from OpenSearch edit filter with settings as described above&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-logtrimmed-ab1e00b02a80957259f1713178d36a32.png" width="1340" height="706" class="img_ev3q"></li>
</ul>
</li>
<li class="">AWS Brokered Service Logs (Beta): If your Cloud.gov organization had already worked with Cloud.gov support to enable publishing of your RDS database logs to Cloudwatch, then you can search for those logs with the filter <code>@version: 1</code>. Most databases, as of December 2024, are not yet publishing their logs to CloudWatch and thus will not appear in OpenSearch.<!-- -->
<ul>
<li class="">Cloud.gov will be expanding the availability of logs from other brokered services in 2025. This is a <a class="" href="https://docs.cloud.gov/platform/services/intro/#support-status">beta feature</a> and subject to change.</li>
<li class="">Cloud.gov is working to make enabling publishing of RDS database logs to CloudWatch a self-service feature of the <a class="" href="https://docs.cloud.gov/platform/services/relational-database/">database broker</a>, but there is no ETA yet for delivery of this feature.</li>
</ul>
</li>
<li class="">JSON log parsing: Custom logs are not at risk of being dropped because of index field limits. JSON logs are now ingested using the <a href="https://opensearch.org/docs/latest/field-types/supported-field-types/flat-object/" target="_blank" rel="noopener noreferrer" class="">flat_object field type</a> in OpenSearch. The <code>flat_object</code> field type allows for <a href="https://opensearch.org/docs/latest/field-types/supported-field-types/flat-object/#using-flat-object" target="_blank" rel="noopener noreferrer" class="">searching nested fields of a JSON object</a> using dot notation.</li>
<li class="">Additional container metrics: We now log additional container metrics, available under the <code>containermetric.name</code> field. Particularly useful is the <code>containermetric.name: cpu_entitlement</code>, which is a way to track whether you're <a href="https://www.cloudfoundry.org/blog/better-way-split-cake-cpu-entitlements/" target="_blank" rel="noopener noreferrer" class="">exceeding the allowed CPU for your apps</a>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reporting-issues-and-getting-help">Reporting Issues and Getting Help<a href="https://docs.cloud.gov/knowledge-base/2024/12/06/migrating-opensearch/#reporting-issues-and-getting-help" class="hash-link" aria-label="Direct link to Reporting Issues and Getting Help" title="Direct link to Reporting Issues and Getting Help" translate="no">​</a></h2>
<p>Report any undocumented issues you encounter, or questions you may have, to <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PHP buildpack failed to clone git repository issue]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/12/02/php-buildpack-failed-to-clone-git-repository-issue/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/12/02/php-buildpack-failed-to-clone-git-repository-issue/</guid>
            <pubDate>Mon, 02 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[On December 2nd, 2024 it was brought to our attention that Cloud.gov customers attempting to push or re-stage applications using PHP buildpack versions 4.6.24 and above were experiencing a “Failed to clone git repository at https://github.com/cloudfoundry/php-buildpack” error.]]></description>
            <content:encoded><![CDATA[<p>On December 2nd, 2024 it was brought to our attention that Cloud.gov customers attempting to push or re-stage applications using PHP buildpack versions 4.6.24 and above were experiencing a “<code>Failed to clone git repository at https://github.com/cloudfoundry/php-buildpack</code>” error.</p>
<p>The reason why this issue is occurring is because the recently updated buildpack versions are trying to clone some git submodules over SSH instead of HTTPS. Cloud.gov supports HTTPS egress for buildpacks during staging, not SSH, as such the buildpack is unable to be fetched and the staging process fails. An <a href="https://github.com/cloudfoundry/php-buildpack/issues/1110" target="_blank" rel="noopener noreferrer" class="">issue</a> with the PHP buildpack has already been posted to the CloudFoundry GitHub.</p>
<p>The solution to this issue is pin the version of the buildpack that you are using with your application to version 4.6.23 or a prior version.</p>
<p>To pin the buildpack version, specify the buildpack version URL in your application manifest under the <code>buildpacks:</code> attribute as shown below.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">buildpacks</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> https</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//github.com/cloudfoundry/php</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">buildpack</span><span class="token comment" style="color:#999988;font-style:italic">#v4.6.23</span><br></span></code></pre></div></div>
<p>If you encounter any difficulties deploying this solution or have any questions, please contact <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a> and we will be happy to assist you.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pages GitHub Repository Best Practices]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/</guid>
            <pubDate>Tue, 23 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Adhering to a set of best practices when it comes to managing GitHub repositories can greatly ease the maintenance burden and drastically improve the developer experience for websites hosted on Cloud.gov Pages. This document should serve as a constructive conversation piece for agencies and not as an audit mechanism. But by utilizing certain code scanning tools, agencies may find it easier to identify and cover certain security controls within their respective Customer Responsibility Matrix (CRM). Here is a useful guide for you to get started with implementing some best practices regarding user permissions and security for your GitHub hosted repositories.]]></description>
            <content:encoded><![CDATA[<p>Adhering to a set of best practices when it comes to managing GitHub repositories can greatly ease the maintenance burden and drastically improve the developer experience for websites hosted on Cloud.gov Pages. This document should serve as a constructive conversation piece for agencies and not as an audit mechanism. But by utilizing certain code scanning tools, agencies may find it easier to identify and cover certain security controls within their respective Customer Responsibility Matrix (CRM). Here is a useful guide for you to get started with implementing some best practices regarding user permissions and security for your GitHub hosted repositories.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="public-vs-private-repositories">Public vs Private repositories<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#public-vs-private-repositories" class="hash-link" aria-label="Direct link to Public vs Private repositories" title="Direct link to Public vs Private repositories" translate="no">​</a></h2>
<p>A repository does <em>not need</em> to be public in order for Pages to be able to build the website and there are no added website security benefits for private repositories; both public and private repositories are acceptable on Pages due to all branches, both public and private, being published publicly when built. When it comes to deciding whether to make your GitHub repository public or private you may consider the following items.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="public">Public<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#public" class="hash-link" aria-label="Direct link to Public" title="Direct link to Public" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="pros">Pros<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#pros" class="hash-link" aria-label="Direct link to Pros" title="Direct link to Pros" translate="no">​</a></h4>
<ul>
<li class="">Easy for Pages engineers to access the codebase and provide support/debug</li>
<li class="">Transparency/High visibility</li>
<li class="">Able to utilize CodeQL free of charge</li>
<li class="">Seamless OpenSSF Allstar integration</li>
<li class="">Collaboration with outside contributors</li>
<li class="">Compliance with open source and transparency initiatives per agency/program</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="cons">Cons<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#cons" class="hash-link" aria-label="Direct link to Cons" title="Direct link to Cons" translate="no">​</a></h4>
<ul>
<li class="">Sensitive information inadvertently hardcoded is immediately visible</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="private">Private<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#private" class="hash-link" aria-label="Direct link to Private" title="Direct link to Private" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="pros-1">Pros<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#pros-1" class="hash-link" aria-label="Direct link to Pros" title="Direct link to Pros" translate="no">​</a></h4>
<ul>
<li class="">Test/Make changes to a website without exposing commits to the public</li>
<li class="">Safeguard sensitive data such as API keys, access tokens or other credentials by <a class="" href="https://docs.cloud.gov/pages/developers/env-vars-on-pages-builds/">using environment variables</a> in the build runtime.
<em>Websites on Pages are all published publicly, user's configuration settings and static site build engine factor into what is included in the site build output.</em></li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="cons-1">Cons<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#cons-1" class="hash-link" aria-label="Direct link to Cons" title="Direct link to Cons" translate="no">​</a></h4>
<ul>
<li class="">Not able to utilize CodeQL for free</li>
<li class="">Potentially out of compliance with agency/program transparency initiatives</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="repository-user-permissions">Repository User Permissions<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#repository-user-permissions" class="hash-link" aria-label="Direct link to Repository User Permissions" title="Direct link to Repository User Permissions" translate="no">​</a></h3>
<p>It is important to designate admin/owner access of the repository to one or more individuals who are either the persistent site owners or else federal employees with the “manager” role within the Pages organization. It is strongly recommended to not grant admin/owner privileges of the repository to any contractors or other temporary employees. This is because in certain instances where actions will need to be taken by either Pages engineers or by customers that require an active user with admin access to a website's repository. Additionally, when adding contributors or collaborators to a private repository it should mirror the member count that your organization has within Pages. Please note that removing an organization member from an organization within Pages will <strong>not</strong> automatically remove them from the repository within GitHub. They will still retain whatever read/write access they have in GitHub until explicitly removed.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="github-repository-security">GitHub Repository Security<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#github-repository-security" class="hash-link" aria-label="Direct link to GitHub Repository Security" title="Direct link to GitHub Repository Security" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="dependabot">Dependabot<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#dependabot" class="hash-link" aria-label="Direct link to Dependabot" title="Direct link to Dependabot" translate="no">​</a></h4>
<p>Dependabot is a useful and highly configurable automated dependency management tool which assists developers with keeping third-party dependencies up-to-date with their latest version. This can benefit smaller developer teams by reducing maintenance overhead. Dependabot scans the repository for outdated dependencies and generates pull requests against whatever branch it is enabled on to update them. Check out our <a class="" href="https://docs.cloud.gov/knowledge-base/2023/05/22/dependabot-with-pages/">knowledge base article on Dependabot</a> to learn how to enable and configure it for your repository.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="branch-protection">Branch Protection<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#branch-protection" class="hash-link" aria-label="Direct link to Branch Protection" title="Direct link to Branch Protection" translate="no">​</a></h4>
<p><a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches" target="_blank" rel="noopener noreferrer" class="">Branch protection</a> is a security feature within GitHub that limits users with write and push access the ability to push directly to any branch where branch protections are enabled. This includes but is not limited to requiring a pull request to merge code, setting the number of pull request reviews required, requiring status checks, dismissing approvals and other configuration options. With good branch protection settings you can protect your repository from an attack by a malicious actor with the stolen credentials from a single maintainer of that repository.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="openssf-allstar">OpenSSF Allstar<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#openssf-allstar" class="hash-link" aria-label="Direct link to OpenSSF Allstar" title="Direct link to OpenSSF Allstar" translate="no">​</a></h4>
<p><a href="https://github.com/ossf/allstar?tab=readme-ov-file#disabling-unwanted-issues-1" target="_blank" rel="noopener noreferrer" class="">Allstar</a> is an open source security tool which monitors organizations and repositories within GitHub for adherence to security best practices and improves the security posture for those organizations. It achieves this by continuously scanning repositories for any breach of enabled <a href="https://github.com/ossf/allstar?tab=readme-ov-file#policies" target="_blank" rel="noopener noreferrer" class="">security policies</a> and then raising an alert for any security remediation findings. This alert can be in the form of a GitHub issue or another type of configured action. In some instances Allstar can automatically resolve the issue on the admin/owner's behalf.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="additional-advanced-feature-settings-for-github-repository-security">Additional Advanced Feature Settings for GitHub Repository Security<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#additional-advanced-feature-settings-for-github-repository-security" class="hash-link" aria-label="Direct link to Additional Advanced Feature Settings for GitHub Repository Security" title="Direct link to Additional Advanced Feature Settings for GitHub Repository Security" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="codeql">CodeQL<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#codeql" class="hash-link" aria-label="Direct link to CodeQL" title="Direct link to CodeQL" translate="no">​</a></h4>
<p><a href="https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning" target="_blank" rel="noopener noreferrer" class="">CodeQL</a>, a GitHub open source security application, is a code analysis tool that automatically finds security vulnerabilities and other software bugs in codebases. Although primarily used for security analysis it can also be used for general code quality analysis as well. It is important to again note that CodeQL is only free to use on public repositories and GitHub Advanced Security must be purchased/enabled in order to utilize the tool on private repositories.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="signed-commits">Signed Commits<a href="https://docs.cloud.gov/knowledge-base/2024/04/23/repository-best-practices/#signed-commits" class="hash-link" aria-label="Direct link to Signed Commits" title="Direct link to Signed Commits" translate="no">​</a></h4>
<p>In conjunction with good user permissions practices and as an added layer of security you can ensure that only commits by members of your Pages organization are made to the repository by having them signed and then verified by GitHub. This increases the authenticity and integrity of your repositories' commit history, especially for those repositories which are public facing. There are various methods when it comes to implementing <a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification" target="_blank" rel="noopener noreferrer" class="">commit signing</a> so be sure to review them in full detail.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Monitoring your application's health]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/03/25/monitoring-app-metrics/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/03/25/monitoring-app-metrics/</guid>
            <pubDate>Mon, 25 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[One of the benefits of hosting your applications on Cloud.gov is that it offers [performance metrics for]]></description>
            <content:encoded><![CDATA[<p>One of the benefits of hosting your applications on Cloud.gov is that it offers <a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html" target="_blank" rel="noopener noreferrer" class="">performance metrics for
monitoring the health of your application</a>.</p>
<p>The most important metrics for monitoring your application's health are the memory and CPU metrics, which can help you identify:</p>
<ul>
<li class="">If your application has enough memory provisioned per instance</li>
<li class="">If your application is experiencing CPU spikes and associated performance issues</li>
<li class="">If you need <a class="" href="https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/">to horizontally scale your application instances</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-note-about-cpu-metrics">A note about CPU metrics<a href="https://docs.cloud.gov/knowledge-base/2024/03/25/monitoring-app-metrics/#a-note-about-cpu-metrics" class="hash-link" aria-label="Direct link to A note about CPU metrics" title="Direct link to A note about CPU metrics" translate="no">​</a></h2>
<p>CPUs are virtualized and shared across application containers on a Diego cell virtual machine (VM).</p>
<p><a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html#container-metrics" target="_blank" rel="noopener noreferrer" class="">The CPU usage figure reported as part of the application metrics represents the CPU usage of an application instance as a percentage of a single CPU core</a>. Since there are usually multiple CPU cores per VM, <strong>it is possible for the CPU usage to exceed 100%</strong>, which means your application is using the equivalent compute power of more than a single CPU core.</p>
<p>A CPU usage figure above 100% is not necessarily problematic. The more important metric for identifying issues is CPU entitlement, which is <a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html#container-metrics" target="_blank" rel="noopener noreferrer" class="">a formula Cloud Foundry uses to determine how much CPU your application <strong>is allowed to use</strong> from the host VM based on its memory capacity</a>.</p>
<p>If the CPU entitlement figure exceeds 100% for any application instance, then the instance is effectively borrowing spare CPU resources from the host VM. Since applications are regularly redistributed across the available host VMs, the amount of spare CPU capacity available on the VM can change, so any instances of CPU entitlement above 100% should be treated as an indication of insufficient application resources and addressed appropriately.</p>
<p><a href="https://docs.cloudfoundry.org/loggregator/container-metrics.html#cpu-entitlement" target="_blank" rel="noopener noreferrer" class="">Cloud Foundry provides a <code>cf</code> CLI plugin for determining if any of your application instances are exceeding their CPU entitlement</a>.</p>
<p>While the CPU usage figure itself does not independently reveal application issues, it is still worth monitoring as a relative value, since sudden spikes in the value can still indicate abnormal performance of your application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="retrieving-current-memory-and-cpu-metrics">Retrieving current memory and CPU metrics<a href="https://docs.cloud.gov/knowledge-base/2024/03/25/monitoring-app-metrics/#retrieving-current-memory-and-cpu-metrics" class="hash-link" aria-label="Direct link to Retrieving current memory and CPU metrics" title="Direct link to Retrieving current memory and CPU metrics" translate="no">​</a></h2>
<p>To retrieve the current memory and CPU usage for your app, you can use the <code>cf app</code> command:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf app APP-NAME</span><br></span></code></pre></div></div>
<p>The output from running that command will look something like:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of application summary printed in a terminal session by the cf app command&amp;quot;" src="https://docs.cloud.gov/assets/images/cf-app-metrics2-a42cd832d234d64e0d949f81c0c187a4.png" width="1366" height="462" class="img_ev3q"></p>
<p>The <code>cpu</code> and <code>memory</code> metrics in the output can be interpreted as follows:</p>
<ul>
<li class=""><code>cpu</code>: percentage of CPU used by the application, as explained above</li>
<li class=""><code>memory</code>: memory used out of the amount of memory allowed for each application instance</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-view-historical-memory-and-cpu-metrics-in-kibana">How to view historical memory and CPU metrics in Kibana<a href="https://docs.cloud.gov/knowledge-base/2024/03/25/monitoring-app-metrics/#how-to-view-historical-memory-and-cpu-metrics-in-kibana" class="hash-link" aria-label="Direct link to How to view historical memory and CPU metrics in Kibana" title="Direct link to How to view historical memory and CPU metrics in Kibana" translate="no">​</a></h2>
<p>While it is useful to view your application's CPU and memory usage at a given point in time, what is usually
more helpful is to see the trends in your application's health metrics over time and in particular whether
they correlate to observed performance issues for your application.</p>
<p>Logs containining these application metrics are already ingested into the <a href="https://logs.fr.cloud.gov/" target="_blank" rel="noopener noreferrer" class="">Elasticsearch/Kibana instance for customer logs</a>. Furthermore, there are already built-in visualizations and dashboards for viewing these metrics for your applications.</p>
<p>To view the dashboards for application metrics, follow these steps:</p>
<ol>
<li class="">
<p>Log in to <a href="https://logs.fr.cloud.gov/" target="_blank" rel="noopener noreferrer" class="">Kibana</a>.</p>
</li>
<li class="">
<p>Click <code>Dashboard</code> in the bookmark links at the top of the page.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Kibana interface with an arrow pointing towards the Dashboard bookmark at the top of the page&amp;quot;" src="https://docs.cloud.gov/assets/images/kibana-click-dashboard-link-63bfaa1166cf9e3de8360899dec9d5f0.png" width="784" height="104" class="img_ev3q"></p>
</li>
<li class="">
<p>Enter <code>App - Metrics</code> in the search bar on the Dashboards page and click the link to the <code>App - Metrics</code> dashboard in the results.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Screenshot of Kibana dashboards search page with App - Metrics as the search query&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-click-dashboard-link-ff7f51a38722f40375f85c5872bfddec.png" width="1706" height="304" class="img_ev3q"></p>
</li>
<li class="">
<p>The <code>App - Metrics</code> dashboard should automatically populate with metrics for a graph of CPU usage, memory usage (in bytes), and disk usage for all of your applications. Add filters (e.g. <code>@cf.space</code>) to limit the results to the desired applications and adjust the time filter to see metrics for the desired time period.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Full-page screenshot of the App - Metrics dashboard in Kibana displaying visualizations of CPU usage, memory usage, and disk usage based on application metrics&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-search-app-metrics-dashboard-bbb8a0c2e68d50d7ffc028ea308bb979.png" width="2522" height="734" class="img_ev3q"></p>
</li>
<li class="">
<p>If you want to see a dashboard of the same application metrics, but grouped by <strong>each application instance</strong> instead of just each application, repeat steps 3 - 4 and search for a dashboard name <code>App - Metrics by instance</code>.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Full-page screenshot of the App - Metrics by instance dashboard in Kibana displaying visualizations of CPU usage, memory usage, and disk usage aggregated by application instance&amp;quot;" src="https://docs.cloud.gov/assets/images/opensearch-app-metrics-dashboard-44286423f9ef0222871fe6f583eefcd3.png" width="2878" height="1638" class="img_ev3q"></p>
</li>
</ol>
<p>If you encounter any difficulties using these dashboards or have any questions about them, please contact <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a> and we would be happy to assist you.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Displaying dynamic content on a Pages static site]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/</guid>
            <pubDate>Wed, 06 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[For many of our customers, a simple static site hosted on Cloud.gov Pages is a lightweight and easy to manage solution for their agency or office. But what about situations where a static site needs to display a small amount of dynamic content; for example, structured data that updates more frequently than the written content, or is provided by another team or application? Certain kinds of data and content are more suitably stored in a database and accessed via an API on page load. While those services aren’t available in Pages, databases and APIs are available to our customers through Cloud.gov.]]></description>
            <content:encoded><![CDATA[<p>For many of our customers, a simple static site hosted on Cloud.gov Pages is a lightweight and easy to manage solution for their agency or office. But what about situations where a static site needs to display a small amount of dynamic content; for example, structured data that updates more frequently than the written content, or is provided by another team or application? Certain kinds of data and content are more suitably stored in a database and accessed via an API on page load. While those services aren’t available in Pages, databases and APIs are available to our customers through Cloud.gov.</p>
<p>Taking advantage of end-to-end Cloud.gov services gives our agency customers baked-in security to help ease their compliance burden, and we provide support for dual agreements to make accessing these services simple. Below, we share how to display dynamic content using a lightweight database and API on Cloud.gov connected to a Pages static website. Once you see how easy it is, we hope you’ll consider situations where your static Pages sites could be enhanced with dynamic content using additional Cloud.gov services.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-youll-need-to-get-started">What you’ll need to get started<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#what-youll-need-to-get-started" class="hash-link" aria-label="Direct link to What you’ll need to get started" title="Direct link to What you’ll need to get started" translate="no">​</a></h2>
<ol>
<li class="">
<p><strong>Some data</strong> you need to store, process, or access separately from the static site. In this case, we pulled a CSV file dataset from the FDIC, a Pages customer, which is hosted on <a href="https://data.gov/" target="_blank" rel="noopener noreferrer" class="">data.gov</a>, another office alongside Cloud.gov in TTS.</p>
</li>
<li class="">
<p>A <strong>database</strong> and environment to store the data, provided by Cloud.gov. In our example, we chose an <a class="" href="https://docs.cloud.gov/platform/services/relational-database/">RDS instance</a>(Relational Database Service) of the PostgreSQL v15 database due to its rich feature set and simple methods of storing data from a CSV.</p>
</li>
<li class="">
<p>A <strong>server-side application</strong> that securely accesses the database and responds to HTTP requests. Our example uses a simple <a href="https://github.com/cloud-gov/pages-example-website-api" target="_blank" rel="noopener noreferrer" class="">API flask application</a> deployed on Cloud.gov</p>
</li>
<li class="">
<p>The <strong>static <a href="https://federalist-31c21015-f923-4733-95df-2e979da3e393.sites.pages.cloud.gov/site/cloud-gov/pages-example-api-website/" target="_blank" rel="noopener noreferrer" class="">website</a></strong> hosted on Cloud.gov Pages. <a href="https://github.com/cloud-gov/pages-example-api-website" target="_blank" rel="noopener noreferrer" class="">Our example</a> uses a simple HTML file, but you could use any static site generator or single-page application on Pages.</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-it-all-comes-together">How it all comes together<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#how-it-all-comes-together" class="hash-link" aria-label="Direct link to How it all comes together" title="Direct link to How it all comes together" translate="no">​</a></h2>
<p>The below diagram shows the relationships between the three services:</p>
<ol>
<li class="">
<p>The PostgreSQL database, which houses the dataset and returns the results found by the query. The fetched data is sent back to the API application, and the API application passes it on to the static site in the response body as JSON.</p>
</li>
<li class="">
<p>The API application first securely connects to the database by retrieving the RDS service credentials via Cloud.gov’s Cloud Foundry environment. Once it establishes a secure connection to the PostgreSQL database, the application executes a SQL query against the database.</p>
</li>
<li class="">
<p>The static website, hosted on Pages, makes an HTTP <code>fetch</code> request for some dynamic content to the Cloud.gov-hosted API application.</p>
</li>
</ol>
<figure class="content-image"><img alt="Diagram of the infrastructure serving dynamic content to a Pages static site. An HTTP request from a static Pages site triggers the Flask API application to get credentials from the env variables in Cloud.gov, then executes a SQL query against the PostgreSQL database. The results returned from the database are passed through the API application and back to the Pages static site through the HTTP response in JSON." src="https://docs.cloud.gov/img/blog/illustrationPagesDynamicContent.png"><figcaption>Figure 1. Dynamic Content Architecture.</figcaption></figure>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="set-up-a-database-using-cloudgovs-rds">Set up a database using Cloud.gov’s RDS<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#set-up-a-database-using-cloudgovs-rds" class="hash-link" aria-label="Direct link to Set up a database using Cloud.gov’s RDS" title="Direct link to Set up a database using Cloud.gov’s RDS" translate="no">​</a></h3>
<p>Before you can create an API to access the data, the data must be available in the appropriate Cloud.gov org and space. It’s relatively straightforward to provision a database of your choice and make it available for querying from other applications using Cloud.gov’s RDS.</p>
<p>When you create an RDS service instance, Cloud.gov automatically creates the default username and password for the database. If you want to allow an application (like our Flask API app) to access that database, you can <a href="https://docs.cloudfoundry.org/devguide/services/application-binding.html#bind" target="_blank" rel="noopener noreferrer" class="">bind that RDS database service</a> to your application to safely expose those credentials as environment variables within the Cloud.gov environment. This means your Cloud.gov API application will have privileges to data that your Pages app will not, which can be useful in separating data concerns and keeping some information private.</p>
<p>In our case, we provisioned a PostgreSQL v15 database instance within Cloud.gov to store some sample data. For the purposes of filling out an example database, we sourced a CSV from FDIC which itemizes recently failed banks, and then imported the CSV into the database’s single row table using the syntax <a href="https://www.postgresql.org/docs/current/sql-copy.html" target="_blank" rel="noopener noreferrer" class="">COPY/FROM</a>.</p>
<p>When queried via the API application, the database will select a number of rows, convert them to a Python dictionary via the <a href="https://www.psycopg.org/psycopg3/docs/advanced/rows.html" target="_blank" rel="noopener noreferrer" class="">Row factories module</a>, and return that collection.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Bank Name                | City          | State | Cert  | Acquiring Institution               | Closing Date | Fund  | id</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-------------------------+---------------+-------+-------+-------------------------------------+--------------+-------+---</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Citizens Bank            | Sac City      | IA    | 8758  | Iowa Trust &amp; Savings Bank           | 3-Nov-23     | 10545 | 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Heartland Tri-State Bank | Elkhart       | KS    | 25851 | Dream First Bank, N.A.              | 28-Jul-23    | 10544 | 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">First Republic Bank      | San Francisco | CA    | 59017 | JPMorgan Chase Bank, N.A.           | 1-May-23     | 10543 | 3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Signature Bank           | New York      | NY    | 57053 | Flagstar Bank, N.A.                 | 12-Mar-23    | 10540 | 4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Silicon Valley Bank      | Santa Clara   | CA    | 24735 | First–Citizens Bank &amp; Trust Company | 10-Mar-23    | 10539 | 5</span><br></span></code></pre></div></div>
<p>If you’re thinking of trying this yourself, know that you aren’t limited to using RDS and PostgreSQL for storing the data; you have your choice of database infrastructure hosted on Cloud.gov. Check out more options for database services provided by Cloud.gov in our CloudFoundry <a class="" href="https://docs.cloud.gov/platform/services/intro/#provisioning-managed-services-through-the-marketplace">marketplace</a>. Please note that database options are limited for those working in a Cloud.gov <a href="hhttps://cloud.gov/sign-up/" target="_blank" rel="noopener noreferrer" class="">sandbox</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="set-up-a-server-api-application-in-your-cloudgov-org-space">Set up a server API Application in your Cloud.gov org space<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#set-up-a-server-api-application-in-your-cloudgov-org-space" class="hash-link" aria-label="Direct link to Set up a server API Application in your Cloud.gov org space" title="Direct link to Set up a server API Application in your Cloud.gov org space" translate="no">​</a></h3>
<p>You may write the server-side API in whatever language you’re comfortable with; we chose a simple Flask application in Python. <a href="https://github.com/cloud-gov/pages-example-website-api" target="_blank" rel="noopener noreferrer" class="">Our example app</a> which is hosted on Cloud.gov serves as the interface between the PostgreSQL database and the Pages website. Through the Flask application’s endpoint, the Pages website can request data and receive structured responses via HTTP.
In our example app, the Flask app fetches the 15 most recent results from the PostgreSQL database table and returns them via HTTP as an JSON response. JSON is a reliable choice for easy parsing from the front-end static site using JavaScript, but you could also send XML, a string, or another data type.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-import-the-modules">1. Import the modules<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#1-import-the-modules" class="hash-link" aria-label="Direct link to 1. Import the modules" title="Direct link to 1. Import the modules" translate="no">​</a></h4>
<p>In order for our example web server to handle HTTP requests, dispatch responses, and interact with the database and environment, we needed a handful of Python modules:</p>
<p><code>- flask</code> for creating the web server and preparing the JSON response</p>
<p><code>- os</code> for reading environment variables and returning the result</p>
<p><code>- cfenv</code> for interacting with Cloud Foundry environment variables</p>
<p><code>- dict_row</code> for fetching database results as dictionaries</p>
<p><code>- flask_cors</code> and <code>CORS</code> for handling Cross-Origin Resource Sharing (CORS), which is what allows Pages and the server to talk to one another even though they’re on separate domains</p>
<p><code>- ConnectionPool</code> for managing the set of open PostgreSQL database connections, this allows for efficient reuse of existing open connections which reduces latency</p>
<p><code>- OperationalError</code> for reporting database connection failures, if a failure occurs the application will be able to recognize it and automatically recreate the connection pool</p>
<p><code>- atexit</code> ensures proper cleanup of database connection pool upon application termination</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-set-up-the-secure-database-connection">2. Set up the secure database connection<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#2-set-up-the-secure-database-connection" class="hash-link" aria-label="Direct link to 2. Set up the secure database connection" title="Direct link to 2. Set up the secure database connection" translate="no">​</a></h4>
<p>Because we’ve set up the database using RDS and bound to the service in this Cloud.gov org space, we have direct access to the database credentials via application environment variables. Cloud.gov and RDS make it easy to set up a secure connection to the database using these environment variables. Here is how we connect to our database using the <code>DATABASE_URL</code> environment variable provided by the Cloud.gov platform in our Flask application:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">aws_rds </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> app_env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get_service</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">name</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"example-website-api-database"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setup_connection_pool</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    database_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"DATABASE_URL"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    pool </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ConnectionPool</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        conninfo</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">database_url</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        min_size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        max_size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> pool</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-define-the-routes">3. Define the routes<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#3-define-the-routes" class="hash-link" aria-label="Direct link to 3. Define the routes" title="Direct link to 3. Define the routes" translate="no">​</a></h4>
<p>The server application can now access the database, so we need it to provide endpoints for our static site to actually make the requests. These endpoints are defined in the Flask application’s routes. Our example app has two endpoints that can handle GET requests.</p>
<ul>
<li class="">The root-level route (<code>"/"</code>) is accessed when an HTTP request is made to the bare domain itself; in our case, it will react to requests of <a href="https://cfpyapi.app.cloud.gov/" target="_blank" rel="noopener noreferrer" class="">https://cfpyapi.app.cloud.gov/</a> with a simple string response letting you know the app is running. It’s a best practice not to use your root-level domain for serving data anything other than some general information about your API service.</li>
<li class="">The second route (<code>"/get_table"</code>) is the one we use for accessing data from the database. When an HTTP request visits <strong><a href="https://cfpyapi.app.cloud.gov/get_table" target="_blank" rel="noopener noreferrer" class="">https://cfpyapi.app.cloud.gov/get_table</a></strong>, the Flask app will execute our <code>get_table()</code> function, which queries the database using the above credentials, finds matching results, and returns them in JSON format. Serving data and handling requests from a route endpoint makes the API more organized and easier to understand. When you need more endpoints for other queries in the future, it’s easy to add more routes.</li>
</ul>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@app</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">route</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> methods</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">try</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"There is a table right behind this door!"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@app</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">route</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/get_table"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> methods</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get_table</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">global</span><span class="token plain"> connection_pool</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">try</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> fetch_fdic_banks</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">connection_pool</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-make-the-api-available-to-your-pages-app">4. Make the API available to your Pages app<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#4-make-the-api-available-to-your-pages-app" class="hash-link" aria-label="Direct link to 4. Make the API available to your Pages app" title="Direct link to 4. Make the API available to your Pages app" translate="no">​</a></h4>
<p>By default, a Flask web server like ours handles HTTP requests, executes the queries, and sends back JSON responses to the client, as long as the request comes from the same origin (or domain). The initial CORS settings assume you would not want websites and applications from other domains to be able to make requests of yours. In order for the app to respond to a request from a static site, that request origin must be specifically allowed in the CORS settings. It’s good security practice to use environment variables whenever you’re able to so we’ve stored our Pages website URL as an <a href="https://cli.cloudfoundry.org/en-US/v6/push.html" target="_blank" rel="noopener noreferrer" class="">environment variable in the application instance</a> using <code>cf push --var ORIGIN='&lt;site&gt;.sites.pages.cloud.gov'</code>.This not only enables us to avoid having to hardcode the full URL but also if we had different environments ie. development, staging and production we can easily change the origin without having to modify the code. If your Pages site uses a custom domain, that would be the origin to use.</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">origin </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"ORIGIN"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">port </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"PORT"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8080</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Flask</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__name__</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">CORS</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> origins</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">origin</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Once your server API can connect to the database, execute queries at specific routes, and respond to only your Pages site domain, you’re ready to deploy. For instructions on how to deploy applications on Cloud.gov, please refer to the official Cloud.gov <a class="" href="https://docs.cloud.gov/platform/deployment/">documentation</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="serve-content-to-the-pages-website">Serve content to the Pages website<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#serve-content-to-the-pages-website" class="hash-link" aria-label="Direct link to Serve content to the Pages website" title="Direct link to Serve content to the Pages website" translate="no">​</a></h3>
<p>Now, you’re ready to request dynamic content from your static site. In our example, the Pages-hosted site is a single <a href="https://github.com/cloud-gov/pages-example-api-website" target="_blank" rel="noopener noreferrer" class="">index.html</a> file with some CSS and image assets and a few lines of JavaScript to make the request and display the dynamic content. We’re using an already minified version of the U.S. Web Design System (USWDS) library from a Content Delivery Network (CDN) so there are no build tasks, transpiling, preprocessing, or compiling in this project – just a simple static site with some nav and the basic structure of a table, waiting to be filled with dynamic content.</p>
<p>There are two steps left: Making the HTTP request to the server app, and then displaying the response that the server app provides. Both are handled with straightforward JavaScript.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-make-the-request">1. Make the request<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#1-make-the-request" class="hash-link" aria-label="Direct link to 1. Make the request" title="Direct link to 1. Make the request" translate="no">​</a></h4>
<p>First, our static site makes an asynchronous request to the API. There are a few ways to do this; our example function <code>getDataFromCloudAPI()</code> uses the fetch pattern to make a request at the <code>/get_table</code> endpoint, waits for the response using <code>await</code>, and then parses it into JSON when the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noopener noreferrer" class="">Promise</a> resolves. We’ve wrapped the request in a <code>try/catch</code> block to log any errors to the console in the browser if the request fails. Once resolved, the function ultimately returns the data requested in JSON.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getDataFromCloudAPI</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> dataJson </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> response </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"https://cfpyapi.app.cloud.gov/get_table"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    dataJson </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">json</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> dataJson</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-display-the-dynamic-content">2. Display the dynamic content<a href="https://docs.cloud.gov/knowledge-base/2024/03/06/website-api/#2-display-the-dynamic-content" class="hash-link" aria-label="Direct link to 2. Display the dynamic content" title="Direct link to 2. Display the dynamic content" translate="no">​</a></h4>
<p>To keep our example simple, our static site displays the API-provided data in a simple HTML table. Using the JSON response data, we first build the table’s headers and then the rows, one by one, and append them all to an empty HTML table element that already exists in the static page. Using the source data to build both the table headers and the content rows means they will always match, even if the data structure on the server or database changes.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createTableHead</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">rowData</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> tableHead </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createElement</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"thead"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> newRow </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> tableHead</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">insertRow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token known-class-name class-name">Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">entries</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">rowData</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">[</span><span class="token parameter">key</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> value</span><span class="token parameter punctuation" style="color:#393A34">]</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> cellIndex</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> newHeader </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createElement</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"th"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      newHeader</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">innerHTML</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> key</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      newRow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">appendChild</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">newHeader</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> tableHead</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createTableBody</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">rowData</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> tableBody </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createElement</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"tbody"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  rowData</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">row</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> rowIndex</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> newRow </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> tableBody</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">insertRow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">rowIndex</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token known-class-name class-name">Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">entries</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">row</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">[</span><span class="token parameter">key</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> value</span><span class="token parameter punctuation" style="color:#393A34">]</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> cellIndex</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> newCell </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> newRow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">insertCell</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">cellIndex</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        newCell</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">innerHTML</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> tableBody</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createTable</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"data-table"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">appendChild</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">createTableHead</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"data-table"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">appendChild</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">createTableBody</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>And that’s it! The static HTML page makes the fetch request to the API on load, then builds the table contents using the response, seamlessly.</p>
<p>Serving dynamic content from a backend database via an API to a static site hosted on Cloud.gov Pages is easy within the Cloud.gov ecosystem. We proudly offer a suite of secure and compliant databases which you can leverage to store data and dynamically display within their Pages websites without the need to manually update the static files or struggle with large data collections checked into the static site repo.</p>
<p>If you’re interested in enhancing your static sites with dynamic content, we’d love to help you set up a dual agreement for Cloud.gov and Pages services with your agency or office. If you’re already a Pages customer, it takes a simple modification to your current IAA to access services from Cloud.gov to get started. Launching an app on Cloud.gov will require an Authorized, and we’re here to help you through every stage. For more information, please reach out to <a href="mailto:inquiries@cloud.gov"><strong>inquiries@cloud.gov</strong></a>.</p>
<p>For support with implementation and general questions about Pages sites, please reach out to <a href="mailto:pages-support@cloud.gov"><strong>pages-support@cloud.gov</strong></a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Cloud.gov continually adapts to dynamic cybersecurity threats]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2024/01/24/how-cloud.gov-continually-adapts-to-dynamic-cybersecurity-threats/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2024/01/24/how-cloud.gov-continually-adapts-to-dynamic-cybersecurity-threats/</guid>
            <pubDate>Wed, 24 Jan 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Managed Information Security]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="managed-information-security">Managed Information Security<a href="https://docs.cloud.gov/knowledge-base/2024/01/24/how-cloud.gov-continually-adapts-to-dynamic-cybersecurity-threats/#managed-information-security" class="hash-link" aria-label="Direct link to Managed Information Security" title="Direct link to Managed Information Security" translate="no">​</a></h2>
<p>Government web applications and services are targeted by a barrage of ever-increasing challenges, probes, and malicious traffic. These attacks try to exploit common vulnerabilities, compromise infrastructure, or disrupt services for legitimate users.
With thousands of customer application instances running on Cloud.​gov, we see many different kinds of attacks. <a class="" href="https://docs.cloud.gov/platform/overview/support/#service-objectives">Our commitments to safety, security, and transparency</a> ensure that our defenses are up-to-date and robust, safeguarding Cloud.​gov customer applications from the impact of high-traffic-volume attacks directed at both the platform and our agency customers.</p>
<p>One of Cloud.gov’s priorities is to make sure that agencies can focus on their core mission without the burden of dealing with the complex and changing discipline of web application security. We ensure that all customer apps on Cloud.gov are protected by a strategic collection of web application security best practices developed to combat the kinds of threats that government websites are uniquely prone to experience. These strategies are part of our more complete security posture, which is continually emerging and evolving in response to the malicious actors and the attacks they attempt.</p>
<p>cloud.gov’s Web Application Firewall (WAF) stands as one protective barrier against various cyber attacks, operating between a web application and the internet. It acts as a vigilant gatekeeper, monitoring, filtering, and blocking malicious HTTP traffic, while allowing legitimate traffic to access appropriate resources. A <a class="" href="https://docs.cloud.gov/platform/technology/platform-security-protections/">specific set of WAF rules</a> define the criteria for allowing or blocking incoming requests to all Cloud.​gov managed websites and applications.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenge-requests-and-rate-limiting">Challenge Requests and Rate Limiting<a href="https://docs.cloud.gov/knowledge-base/2024/01/24/how-cloud.gov-continually-adapts-to-dynamic-cybersecurity-threats/#challenge-requests-and-rate-limiting" class="hash-link" aria-label="Direct link to Challenge Requests and Rate Limiting" title="Direct link to Challenge Requests and Rate Limiting" translate="no">​</a></h2>
<p>In order to make sure that an HTTP request to access a given web application is a legitimate visit and not a bot, Cloud.gov issues a silent browser challenge. It’s similar to a CAPTCHA, but doesn’t require the visitor to successfully solve a puzzle, as it runs in the background of the browser. This approach helps implement effective rate limiting, managing spikes in requests during high-traffic events, and separating legitimate traffic from probing or DDOS-style attacks. Cloud.gov’s WAF rules also make sure that a single IP address can pass no more than 2,000 of these challenges within a 5-minute period, so that even as malicious attacks become more convincing, customer applications on Cloud.gov remain available and responsive.</p>
<p>After implementing these WAF rules, we monitored traffic surges to ensure that the change handled situations resembling these types of attacks without any negative impact to Cloud.gov customers. For example, consider this graph of traffic across the entire platform from November 7th, 2023:</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;This line graph compares the Challenges issued to IP Addresses after exceeding HTTP request rate limit to all allowed requests. From 8:00 to 16:00, all allowed requests line hovered around the 400,000 tick on the Y-axis, indicating requests. Over the same timeframe, the challenges after rate limit line is near zero until about 12:00, where it rises slowly until about 12:20 and then rapidly, spiking a few times between the ticks at 1.2 and 1.4 Million requests just after 13:00, then drops immediately back to zero around 13:30 and remains near zero until 16:00, where the graph ends&amp;quot;" src="https://docs.cloud.gov/assets/images/illustrationLowRepBlockedRequests@2x-2f1b9151c69c15519d71ee7d0717bc26.png" width="1461" height="824" class="img_ev3q"></p>
<figure class="content-image"><img alt="This line graph compares the Challenges issued to IP Addresses after exceeding HTTP request rate limit to all allowed requests. From 8:00 to 16:00, all allowed requests line hovered around the 400,000 tick on the Y-axis, indicating requests. Over the same timeframe, the challenges after rate limit line is near zero until about 12:00, where it rises slowly until about 12:20 and then rapidly, spiking a few times between the ticks at 1.2 and 1.4 Million requests just after 13:00, then drops immediately back to zero around 13:30 and remains near zero until 16:00, where the graph ends" src="https://docs.cloud.gov/img/blog/illustrationLowRepBlockedRequests@2x.png"><figcaption>The dotted red line above illustrates a surge in requests that received a challenge once their IP exceeded the 2,000 per 5-minute rate limit via the WAF rule. At the same time, all allowed requests (as illustrated by the solid blue line) remained stable, allowing legitimate traffic to continue uninterrupted to Cloud.​gov customer applications.</figcaption></figure>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reputation-lists">Reputation Lists<a href="https://docs.cloud.gov/knowledge-base/2024/01/24/how-cloud.gov-continually-adapts-to-dynamic-cybersecurity-threats/#reputation-lists" class="hash-link" aria-label="Direct link to Reputation Lists" title="Direct link to Reputation Lists" translate="no">​</a></h2>
<p>Another element in Cloud.gov's WAF strategy is the use of existing reputation lists to exclude known potentially malicious or automated traffic that originates from specific IP addresses. At times, traffic surges to customer applications come from IP addresses that were previously determined to be bots or other threats. Cloud.gov protects all of our customer applications by blocking traffic from these known, low-reputation IP addresses. We monitored a potential attack from known low-reputation IP addresses on the evening of November 3rd, and despite seeing more than one million requests in a span of 15 minutes from these IP addresses, the reputation list WAF rule blocked the vast majority of the potentially malicious traffic:</p>
<figure class="content-image"><img alt="This line graph compares the number of allowed vs blocked HTTP Requests for a 2-hour period from 16:00 to 18:00. Allowed requests are indicated in a thick, solid blue line and are relatively stable at around 400,000 requests for the entire duration, with a small peak at just over 500,000 between 17:00 and 17:15. Total blocked requests is identified with a dark red dashed line, and it is near zero for most of the graph, except for a sharp spike up to nearly 1.5 million requests between 17:00 and 17:15. In addition to total blocked requests, there is a bright red solid line indicating requests that were blocked specifically because of the IP Reputation blocked rule, and it follows the same shape and spike of the line for all blocked requests, peaking just slightly below at about 1.25 million requests" src="https://docs.cloud.gov/img/blog/illustrationChallengeRequests@2x.png"></figure>
<p>Just as the Cloud.gov web application security approach guards against known threats using adaptive reputation lists, the Cloud.gov team flexibly and skillfully reacts to new situations. Real-world incidents, like a surge in potentially malicious traffic experienced last October, serve as valuable lessons for how cyber threats are changing for government web applications. Our team not only responds quickly during these incidents but actively works on proactive measures to prevent future occurrences. This iterative process of learning and improvement ensures that our security measures adapt to emerging challenges. We publish updates like these to reflect our total commitment to providing a resilient and reliable platform for our users.</p>
<p>Operating as a public entity in the government space means that malicious actors will regularly attempt to disrupt the services being provided to customers and stakeholders or to compromise the underlying infrastructure. At Cloud.gov, we strive to make sure agencies can trust that their applications are in capable hands, allowing their teams to focus on innovation and development while we handle the rest.</p>
<p>If your development team is interested in hearing more about Cloud.​gov, scheduling a demo, or getting access to a free sandbox, email us at <a href="mailto:support@cloud.gov" target="_blank" rel="noopener noreferrer" class="">support@cloud.gov</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hosting Single Page Applications on Pages]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2023/11/09/single-page-application/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2023/11/09/single-page-application/</guid>
            <pubDate>Thu, 09 Nov 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Cloud.gov Pages hosts static sites, but this doesn’t mean that developers are limited to only using “static site generators”: anything that can be compiled down into HTML can be run on Pages. You can use a single-page application framework like Vue.js, Svelte, Angular, React, etc. and host it seamlessly on the Pages platform. This is achieved via the npm run pages command which allows developers to add a custom build script, and we’ll automatically publish everything in the _site folder. For this particular single page application we’ll be leveraging vite as our build tool.]]></description>
            <content:encoded><![CDATA[<p>Cloud.gov Pages hosts static sites, but this doesn’t mean that developers are limited to only using <a href="https://jamstack.org/generators/" target="_blank" rel="noopener noreferrer" class="">“static site generators”</a>: anything that can be compiled down into HTML can be run on Pages. You can use a single-page application framework like Vue.js, Svelte, Angular, React, etc. and host it seamlessly on the Pages platform. This is achieved via the <code>npm run pages</code> command which allows developers to add a custom build script, and we’ll automatically publish everything in the <code>_site</code> folder. For this particular single page application we’ll be leveraging <a href="https://vitejs.dev/guide/why.html" target="_blank" rel="noopener noreferrer" class="">vite</a> as our build tool.</p>
<p>In this example we will be taking a look at a simple single-page application which uses the React library and React Router v6. You can view a repository with a full example <a href="https://github.com/cloud-gov/pages-example-spa" target="_blank" rel="noopener noreferrer" class="">here</a> and see the results in Pages <a href="https://federalist-01aa8660-8aca-452d-a270-5e58ffa18645.sites.pages.cloud.gov/preview/cloud-gov/pages-example-spa/content/" target="_blank" rel="noopener noreferrer" class="">here</a>. There are also more detailed instructions on how to run this locally in the repositories’ README.md. This article serves as a high level overview and will highlight three key features:</p>
<ul>
<li class="">Application routing</li>
<li class="">Environment variables</li>
<li class="">404 Pages</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-routing">Application Routing<a href="https://docs.cloud.gov/knowledge-base/2023/11/09/single-page-application/#application-routing" class="hash-link" aria-label="Direct link to Application Routing" title="Direct link to Application Routing" translate="no">​</a></h2>
<p>Static site generators like Jekyll and Hugo handle routing by creating an HTML file at each path that can be requested by the user. For single-page applications, we will only render one HTML file: index.html, which loads the JavaScript necessary for running our application and router.</p>
<p>All of the routing is located in the <code>main.jsx</code> file. Here we import all our components, CSS and functions. We create the <code>&lt;BrowserRouter&gt;</code> and use the <code>&lt;RouterProvider&gt;</code> to provide that router to our application. The parent route registers a <code>Layout</code> component which essentially wraps all the other page components thus providing a uniform structure/design for all the components.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> router </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createBrowserRouter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">createRoutesFromElements</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// set route as the path plus layout</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Route</span><span class="token plain"> path</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"/"</span><span class="token plain"> element</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Layout</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Route</span><span class="token plain"> index element</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Home</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Route</span><span class="token plain"> path</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"stuff"</span><span class="token plain"> element</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Stuff</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Route</span><span class="token plain"> path</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"contact"</span><span class="token plain"> element</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Contact</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Route</span><span class="token plain"> path</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"*"</span><span class="token plain"> element</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Page404</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token maybe-class-name">Route</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">basename</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">import</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">meta</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">BASE_URL</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">createRoot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getElementById</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"root"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">StrictMode</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">RouterProvider</span><span class="token plain"> router</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">router</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token maybe-class-name">React</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">StrictMode</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Additionally within the <code>Layout</code> component is where we house all the <code>NavLinks</code> and <code>navbar</code> which are located at the top of the page. The <code>Outlet</code> component tells the <code>react router</code> where to output the child route page components within the layout.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Layout</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">Component</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">h1</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token maybe-class-name">Simple</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">SPA</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">h1</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">ul className</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"header"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">li</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">NavLink</span><span class="token plain"> to</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"/"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token maybe-class-name">Home</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token maybe-class-name">NavLink</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">li</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">li</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">NavLink</span><span class="token plain"> to</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"stuff"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token maybe-class-name">Stuff</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token maybe-class-name">NavLink</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">li</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">li</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">NavLink</span><span class="token plain"> to</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"contact"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token maybe-class-name">Contact</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token maybe-class-name">NavLink</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">li</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">ul</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">div className</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"content"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Outlet</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>It’s important to remember that none of these routes are creating new HTML files at a given path, they are only rendering in the browser (unless you prerender with <a href="https://github.com/stereobooster/react-snap" target="_blank" rel="noopener noreferrer" class="">react-snap</a>). We’ll see how to handle situations when the URL doesn’t match the HTML file in a later section.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="environment-variables">Environment variables<a href="https://docs.cloud.gov/knowledge-base/2023/11/09/single-page-application/#environment-variables" class="hash-link" aria-label="Direct link to Environment variables" title="Direct link to Environment variables" translate="no">​</a></h2>
<p>Pages provides <a class="" href="https://docs.cloud.gov/pages/developers/env-vars-on-pages-builds/">certain environment variables</a> in each build container and you can also add customer variables in your “Site Settings”. In the case of <code>vite</code>, the library we’re using in this example, <a href="https://vitejs.dev/guide/env-and-mode" target="_blank" rel="noopener noreferrer" class="">we are using a single variable provided by Pages</a> in two separate places: - <code>BASEURL</code>: This variable is supplied by the Pages build container and cannot be modified. This will insert the Pages site path based on the branch and associated domain. We’ll utilize this environment variable in our config file, <code>vite.config.js</code>, to set the <a href="https://vitejs.dev/config/shared-options.html#base" target="_blank" rel="noopener noreferrer" class="">base</a> variable which will be used to update our assets path.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token literal-property property" style="color:#36acaa">base</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">BASEURL</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Once the <code>base</code> variable is set in the vite configuration, it statically injects a variable, <code>import.meta.env.BASE_URL</code>, at build time. In our <code>main.jsx</code> file react router can use that variable to set <a href="https://reactrouter.com/en/main/routers/create-browser-router#optsbasename" target="_blank" rel="noopener noreferrer" class=""><code>opts.basename</code></a> which ensures that routing is handled correctly regardless of where the application is served from. When a site is viewed at a non-production domain or preview URL it is not served from the root of the domain but rather a sub path.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> router </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">createBrowserRouter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   …</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token literal-property property" style="color:#36acaa">basename</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">import</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">meta</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">BASE_URL</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="404-pages">404 Pages<a href="https://docs.cloud.gov/knowledge-base/2023/11/09/single-page-application/#404-pages" class="hash-link" aria-label="Direct link to 404 Pages" title="Direct link to 404 Pages" translate="no">​</a></h2>
<p>In our application code, we created a 404 page as another component to be imported into the <code>index.jsx</code> file to be handled by <code>react-router</code>. The Route for the 404 page was set as a wildcard catch-all so that when any path entered is not <code>/</code>, <code>/contact</code> or <code>/stuff</code> the Page404 component will be rendered.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Route</span><span class="token plain"> path</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"*"</span><span class="token plain"> element</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Page404</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token operator" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>
<p>If users navigate to a sub-path of your site directly, we need special handling for this type of 404 because the application will not have loaded your index.jsx file (or associated router).</p>
<p>It is important to note that:</p>
<ol>
<li class="">
<p>Specifically for any single-page applications hosted on Pages you will need to reach out to an <a class="" href="https://docs.cloud.gov/pages/using-pages/customization/#custom-domain-404-page">Pages operator to manually set your custom 404</a> behavior to point to index.html.</p>
</li>
<li class="">
<p>This will only work on your production URL, and only when you have a custom domain. For preview links, you’ll need to navigate to the base URL first before moving on to other paths.</p>
</li>
</ol>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Scaling your Cloud.gov applications]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/</guid>
            <pubDate>Mon, 07 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Importance of multiple application instances]]></description>
            <content:encoded><![CDATA[<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="importance-of-multiple-application-instances">Importance of multiple application instances<a href="https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/#importance-of-multiple-application-instances" class="hash-link" aria-label="Direct link to Importance of multiple application instances" title="Direct link to Importance of multiple application instances" translate="no">​</a></h3>
<p>One of the benefits of Cloud.gov is the ability to <a class="" href="https://docs.cloud.gov/platform/deployment/">deploy applications with a simple command</a>.</p>
<p>By default, applications are deployed with a single instance which handles all traffic and load for your application. The downside of a single application instance is that if you have unexpected surges in application load, it is likely that your instance may run out of available CPU or memory or both, leading to an outage for your application.</p>
<p>To increase your application's ability to respond to requests, also known as availability, you can horizontally scale your application by running multiple application instances. When you have multiple application instances, your application requests are load-balanced among them to ensure that no single instance is prematurely overloaded, thus maximizing your availability.</p>
<p>By default, the routing infrastructure in Cloud.gov <a href="https://docs.cloudfoundry.org/concepts/http-routing.html#balancing-algorithm" target="_blank" rel="noopener noreferrer" class="">distributes requests to application instances using a <code>round-robin</code> algorithm</a>.</p>
<p>Running multiple application instances also increases the chances that your application will be <a href="https://docs.cloudfoundry.org/concepts/diego/diego-auction.html#auction" target="_blank" rel="noopener noreferrer" class="">balanced across availability zones</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-scale-your-application-instances">How to scale your application instances<a href="https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/#how-to-scale-your-application-instances" class="hash-link" aria-label="Direct link to How to scale your application instances" title="Direct link to How to scale your application instances" translate="no">​</a></h3>
<p>Using the <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/deploy-app.html#custom-cf-push" target="_blank" rel="noopener noreferrer" class="">cf push command</a>, you can use the <code>-i</code> flag to indicate the number of application instances you would like.</p>
<p>For example, pushing an application with 2 instances:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf push myapp -i 2</span><br></span></code></pre></div></div>
<p>Additionally, you can also define the number of application instances in your application <code>manifest.yml</code> file with the <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#instances" target="_blank" rel="noopener noreferrer" class=""><code>instances</code> manifest attribute</a>.</p>
<p>An example for defining an application with 2 instances in your <code>manifest.yml</code> file:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">    memory: 512mb</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    instances: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    applications:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        name: myapp</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        path: .</span><br></span></code></pre></div></div>
<p>Please note the default number of instances is 1 instance.</p>
<p>You can also use the <a href="http://docs.cloudfoundry.org/devguide/deploy-apps/cf-scale.html" target="_blank" rel="noopener noreferrer" class="">cf scale</a> command to increase the number of instances for a running app.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf scale myapp -i 2</span><br></span></code></pre></div></div>
<p>Please note that running multiple instances may sometimes cause scheduled tasks or data loads to run multiple times. This issue can be prevented by updating scheduled tasks to use the <a class="" href="https://docs.cloud.gov/platform/management/multiple-instances/#managing-multiple-instances-with-cf-instance-index"><code>CF_INSTANCE_INDEX</code> environment variable</a>, which denotes a specific application instance number.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-instances-and-memory-usage">Application instances and memory usage<a href="https://docs.cloud.gov/knowledge-base/2023/08/07/advantages-of-multiple-application-instances/#application-instances-and-memory-usage" class="hash-link" aria-label="Direct link to Application instances and memory usage" title="Direct link to Application instances and memory usage" translate="no">​</a></h3>
<p>Each individual application instance utilizes the same amount of memory that is specified in the application manifest or indicated in the <code>cf push</code> command. Please note that the application cannot use more than the <a class="" href="https://docs.cloud.gov/platform/management/limits/">defined memory quota for your org</a>.</p>
<p>For example, if the org <code>my-example-org</code> had:</p>
<ul>
<li class="">a memory quota of 3 GB and were hosting a single application <code>myapp</code></li>
<li class="">256 MB of memory per application instance</li>
<li class="">4 application instances</li>
</ul>
<p>Then, the application would be utilizing 1 GB (256 MB * 4 instances) of the org’s 3 GB total memory quota. This would leave 2 GB available for the org to otherwise use.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Configuring Dependabot]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2023/05/22/dependabot-with-pages/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2023/05/22/dependabot-with-pages/</guid>
            <pubDate>Mon, 22 May 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[GitHub Dependabot defined]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="github-dependabot-defined">GitHub Dependabot defined<a href="https://docs.cloud.gov/knowledge-base/2023/05/22/dependabot-with-pages/#github-dependabot-defined" class="hash-link" aria-label="Direct link to GitHub Dependabot defined" title="Direct link to GitHub Dependabot defined" translate="no">​</a></h2>
<p>Dependabot is a feature of GitHub whose main purpose is to assist developers in staying on top of their dependency ecosystem. It does this by automating the dependency update process which in turn proactively addresses any potential security concerns. Dependabot also explicitly raises pull requests to address security vulnerabilities in dependencies and alerts developers to the precise location in the code where the vulnerabilities are. When enabled, it achieves this by scanning a project's dependency files such as package manifests (ie. <code>package.json</code>, <code>Gemfile</code>) or configuration files to identify dependencies and their versions. It then compares the current versions against the latest versions in the relevant package registries. As a developer woking on a site hosted on Pages you may have seen many of these types of alerts/pull requests in your given repository. This article will explain on how to effectively manage these alerts without compromising your code's security.</p>
<p>There are 3 distinct functions of Dependabot.</p>
<ul>
<li class="">
<p><strong>Dependabot alerts</strong>: Alerts regarding dependency vulnerabilities where pull requests are automatically opened.</p>
</li>
<li class="">
<p><strong>Dependabot security updates</strong>: Additional alerts/information regarding vulnerabilities in any out-of-date dependencies where a vulnerability alert (non mergeable pull request) is opened in relation to the initial out of date dependency alert. If applicable it is linked to the actual dependency pull request.</p>
</li>
<li class="">
<p><strong>Dependabot version updates</strong>: Automatic pull requests opened when version bumps are available for dependencies.</p>
</li>
</ul>
<p>* For Pages users with existing jekyll sites Dependabot alerts was automatically enabled upon launch. This is not the case for users who have 11ty or Gatsby based sites where by default all Dependabot services are disabled upon launch.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-locate-and-turn-on-dependabot">Where to locate and turn on dependabot<a href="https://docs.cloud.gov/knowledge-base/2023/05/22/dependabot-with-pages/#where-to-locate-and-turn-on-dependabot" class="hash-link" aria-label="Direct link to Where to locate and turn on dependabot" title="Direct link to Where to locate and turn on dependabot" translate="no">​</a></h2>
<p>To enable any of the Dependabot features navigate to the rightmost tab “settings” in the GitHub repository. On the left hand panel under security select “Code security and analysis”. Here you can enable either of the three previously discussed settings. You can enable Dependabot alerts and Dependabot version updates singularly as they are mutually exclusive of the feature. Enabling Dependabot security updates will also enable Dependabot alerts as it is reliant on alerts to function.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-locate-and-configure-the-dependabotyml-file">Where to locate and configure the dependabot.yml file<a href="https://docs.cloud.gov/knowledge-base/2023/05/22/dependabot-with-pages/#where-to-locate-and-configure-the-dependabotyml-file" class="hash-link" aria-label="Direct link to Where to locate and configure the dependabot.yml file" title="Direct link to Where to locate and configure the dependabot.yml file" translate="no">​</a></h2>
<p>The best way to take advantage of Dependabot while not getting overwhelmed by the amount of pull requests opened is to override the default behavior by customizing the <code>dependabot.yml</code> file which is located in the <code>.github</code> folder of the repository. You can either create it manually or have it automatically generated when enabling Dependabot version updates.</p>
<p>There are certain configuration options which can be set in your <code>dependabot.yml</code> file which will help reduce noise and cut down the amount of open pull requests in your repository. The options that we will focus on specifically are as follows:</p>
<p><code>interval</code>: Set the frequency that Dependabot will check for new versions for each defined package manager.</p>
<br>
<p><code>open-pull-requests-limit</code>: Modify the max limit of pull requests opened for version updates.</p>
<br>
<p><code>ignore</code>: Explicitly ignore specific dependencies, versions and update-types.</p>
<br>
<p><code>target-branch</code>: Specify a different branch for manifest files and for pull requests instead of the default branch.</p>
<p>For a complete list of configuration options and implementations, visit the GitHub site via <a href="https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file" target="_blank" rel="noopener noreferrer" class="">Configuration options for the dependabot.yml file</a>.</p>
<p>This example <code>dependabot.yml</code> file is for any Jekyll site running on Pages. In this case there are two defined package ecosystems which are npm and bundler, both located in the root directory. Specifically for the npm package we’ve set the conditions for Dependabot to check for dependency updates once a week, on Monday, while specifying the time and timezone. By default, Dependabot is set to the UTC timezone. We’ve added and set the condition <code>open-pull-requests-limit</code> to the value 2 so no matter how many updates there are, Dependabot will only open 2 pull requests a week maximum which will drastically cut down on noise. By default, Dependabot opens a maximum of five pull requests for version updates. We have also set an <code>ignore</code> condition for the dependency <code>minimatch</code> which will ignore all updates through version 3, effectively pinning it at its current version for the time being. For the bundler package manager we have kept the same conditions as with npm except we have set the frequency interval to monthly which by default will be the first Monday of the month. Although this is in the same yaml file, conditions set for each package-ecosystem are independent of each other. We have also specified a bundler dependency version to ignore.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">version: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">updates:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  - package-ecosystem: "npm"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    directory: "/"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    schedule:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        internval: "weekly"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        day: "monday"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        time: "07:57"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        timezone: "America/New_York"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    open-pull-requests-limit: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ignore:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        -dependency-name: "minimatch"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        versions: ["^3.x"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">- package-ecosystem: "bundler"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  directory: "/"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  schedule:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    interval: "monthly"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    time: "07:57"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    timezone: "America/New_York"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">open-pull-requests-limit: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ignore:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -dependency-name: "nokogiri"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    versions: "~1.13.5"</span><br></span></code></pre></div></div>
<p>In this example an 11ty site is used and we have specfified our npm package manager once again. We have set dependabot to check for version updates daily by specifying "daily" as the interval. We have set the branch that dependabot will run checks against as our <code>staging</code> branch by utilizing the "target-branch" option. By default, Dependabot will check for manifest files on the production branch and raise pull requests for version updates against it. You can override this behavior by explicitly setting the <code>target-branch</code> condition to another branch and have pull requests opened against it instead of your main branch which is what we have done here. It may be easier for Pages users to run more frequent version checks against a staging type branch as opposed to the main branch to make pull requests and alerts more manageable. We have also set Dependabot to ignore all version updates for 3.0 on the dependency <code>rimraf</code> with a pull request limit of 2.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">version: 2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">updates:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    -package-ecosystem: "npm"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    directory: "/"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    schedule:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        interval: "daily"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        timezone: "America/New_York"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        time: "10:30"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    target-branch: "staging"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ignore:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        - dependency-name: "rimraf"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          versions: ["^3.x"]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    open-pull-requests-limit: 2</span><br></span></code></pre></div></div>
<p><strong><em>Please note that the dependencies used in this article were for example use only. We do not advocate for the explicit neglect of specific dependencies. It is up to each developers best judgement on how to best address version updates.</em></strong></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sidecar Processes]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/</guid>
            <pubDate>Tue, 18 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[What is a sidecar process?]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-a-sidecar-process">What is a sidecar process?<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#what-is-a-sidecar-process" class="hash-link" aria-label="Direct link to What is a sidecar process?" title="Direct link to What is a sidecar process?" translate="no">​</a></h2>
<p>Sidecar processes are additional processes you can run in the same container as your application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-do-sidecar-processes-work">How do sidecar processes work?<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#how-do-sidecar-processes-work" class="hash-link" aria-label="Direct link to How do sidecar processes work?" title="Direct link to How do sidecar processes work?" translate="no">​</a></h2>
<p>When deploying a sidecar with your application Cloud Foundry packages the code and configuration needed for running the application and sidecar in the same droplet. The droplet is then deployed in the same container with the application and sidecar being deployed in parallel. The application and sidecar have independent health checks.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-case">Use Case<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#use-case" class="hash-link" aria-label="Direct link to Use Case" title="Direct link to Use Case" translate="no">​</a></h2>
<p>Sidecars can be used on processes which depend on each other or need to run in the same container.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-are-some-example-uses">What are some example uses?<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#what-are-some-example-uses" class="hash-link" aria-label="Direct link to What are some example uses?" title="Direct link to What are some example uses?" translate="no">​</a></h2>
<p>Sidecar processes are useful for things such as application monitoring processes or a process that allows for a centralized server to deliver external configuration properties to an application and management of that configuration across different environments.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-do-you-deploy-sidecar-processes">How do you deploy sidecar processes?<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#how-do-you-deploy-sidecar-processes" class="hash-link" aria-label="Direct link to How do you deploy sidecar processes?" title="Direct link to How do you deploy sidecar processes?" translate="no">​</a></h2>
<p>You can push sidecar processes with your app by using one of two methods:</p>
<ul>
<li class="">Using an app manifest. For instructions, see <a href="https://docs.cloudfoundry.org/devguide/sidecars.html#create" target="_blank" rel="noopener noreferrer" class="">Push an App with a Sidecar Using an App Manifest</a>.</li>
<li class="">With a custom buildpack. For instructions, see <a href="https://docs.cloudfoundry.org/buildpacks/sidecar-buildpacks.html" target="_blank" rel="noopener noreferrer" class="">Sidecar Buildpacks</a>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-are-some-limitations-and-things-to-keep-notice-of">What are some limitations and things to keep notice of?<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#what-are-some-limitations-and-things-to-keep-notice-of" class="hash-link" aria-label="Direct link to What are some limitations and things to keep notice of?" title="Direct link to What are some limitations and things to keep notice of?" translate="no">​</a></h2>
<ul>
<li class="">The start and stop order of app processes and their sidecars is undefined.</li>
<li class="">App processes and sidecars are codependent: If either crashes or exits, the other does also.</li>
<li class="">Sidecars are currently not independently scalable. Sidecars share resources with the main application process and other sidecars within the container.</li>
<li class="">Sidecars only support process-based health checks. HTTP health checks for sidecars are not currently supported.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="specific-java-application-requirements">Specific Java application requirements<a href="https://docs.cloud.gov/knowledge-base/2023/04/18/Sidecar-Processes/#specific-java-application-requirements" class="hash-link" aria-label="Direct link to Specific Java application requirements" title="Direct link to Specific Java application requirements" translate="no">​</a></h2>
<p>Linked here are specific considerations for <a href="https://docs.cloudfoundry.org/devguide/sidecars.html#java" target="_blank" rel="noopener noreferrer" class="">Java applications</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Debian CloudFoundry key not accessible by wget / curl on Ubuntu]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2023/03/28/CloudFoundry-Key-Error/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2023/03/28/CloudFoundry-Key-Error/</guid>
            <pubDate>Tue, 28 Mar 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[CloudFoundry key error]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cloudfoundry-key-error">CloudFoundry key error<a href="https://docs.cloud.gov/knowledge-base/2023/03/28/CloudFoundry-Key-Error/#cloudfoundry-key-error" class="hash-link" aria-label="Direct link to CloudFoundry key error" title="Direct link to CloudFoundry key error" translate="no">​</a></h2>
<p>On 3/28/2023, at approximately 10:35 AM ET, it was noted that due to an upstream CloudFoundry issue the <a href="https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key" target="_blank" rel="noopener noreferrer" class="">CloudFoundry key</a> is not accessible by typical wget or curl requests on Ubuntu using the CloudFoundry Command Line Interface. Despite the <a href="https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key" target="_blank" rel="noopener noreferrer" class="">url</a> being accessible by internet browser, when users attempt to use the wget command, it would be empty. Additionally curl requests would receive a 403 error / access denied error message. The work around for this issue is by providing a user agent with curl's -A option as noted in this <a href="https://github.com/cloudfoundry/cli/issues/2390" target="_blank" rel="noopener noreferrer" class="">issue ticket</a> on the CloudFoundry github.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="status-update-and-issue-resolution">Status update and issue resolution<a href="https://docs.cloud.gov/knowledge-base/2023/03/28/CloudFoundry-Key-Error/#status-update-and-issue-resolution" class="hash-link" aria-label="Direct link to Status update and issue resolution" title="Direct link to Status update and issue resolution" translate="no">​</a></h2>
<p>On 3/28/2023, at approximately 6:18 PM ET, the upstream issue was addressed and resolved as stated in this <a href="https://github.com/cloudfoundry/cli/issues/2390" target="_blank" rel="noopener noreferrer" class="">issue ticket</a> on the CloudFoundry github.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Connecting PostgreSQL RDS instance to S3]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/</guid>
            <pubDate>Mon, 13 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[This method can be used to load a large amount of data into an RDS instance running on Cloud.gov and utilizes an AWS PostgreSQL S3 extension in the process described in the AWS documentation for Importing data from S3 into RDS for PostgreSQL.]]></description>
            <content:encoded><![CDATA[<p>This method can be used to load a large amount of data into an RDS instance running on Cloud.gov and utilizes an AWS PostgreSQL S3 extension in the process described in the AWS documentation for <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PostgreSQL.S3Import.html" target="_blank" rel="noopener noreferrer" class="">Importing data from S3 into RDS for PostgreSQL</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h2>
<p>This process, outlined in the AWS documentation, will work with your Cloud.gov PostgreSQL database and S3 buckets, given the following:</p>
<ul>
<li class="">You have created a <a class="" href="https://docs.cloud.gov/platform/services/relational-database/#create-an-instance">PostgreSQL RDS database with the aws-rds broker in your space</a>.</li>
<li class="">You have created an <a class="" href="https://docs.cloud.gov/platform/services/s3/#how-to-create-an-instance">S3 bucket with the s3-broker service in your space</a>.</li>
<li class="">You have created a <a class="" href="https://docs.cloud.gov/platform/services/s3/#interacting-with-your-s3-bucket-from-outside-cloudgov">service-key and retrieve the credentials for your S3 bucket</a>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="aws-s3-extension">AWS S3 Extension<a href="https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/#aws-s3-extension" class="hash-link" aria-label="Direct link to AWS S3 Extension" title="Direct link to AWS S3 Extension" translate="no">​</a></h2>
<p>First you must install <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PostgreSQL.S3Import.html#USER_PostgreSQL.S3Import.InstallExtension" target="_blank" rel="noopener noreferrer" class="">the AWS S3 extension</a>.</p>
<p>You will need to access the PostgreSQL database on the cli using one of the methods detailed <a class="" href="https://docs.cloud.gov/platform/services/relational-database/#tunneling-to-your-database">here</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="information-needed">Information needed<a href="https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/#information-needed" class="hash-link" aria-label="Direct link to Information needed" title="Direct link to Information needed" translate="no">​</a></h2>
<p>Once you have installed the AWS S3 extension, you then need to gather information to provide for the PostgreSQL RDS to S3 connection function which consist of:</p>
<ul>
<li class="">
<p>The name of the table on your RDS for PostgreSQL DB instance</p>
<p>This is the table into which the <code>aws_s3.table_import_from_s3</code> function is to import the data.</p>
</li>
<li class="">
<p>The S3 bucket name</p>
</li>
<li class="">
<p>The S3 file path</p>
</li>
<li class="">
<p>The S3 file type</p>
<p>These can be obtained from the service key for your S3 service. To get the credentials such as the bucket name, region and file type, these can be obtained from the service key, you can run <code>cf service-key &lt;SERVICE_INSTANCE_NAME&gt; &lt;KEY_NAME&gt;</code>; you will see a JSON description of the credentials. Treat these values as sensitive!</p>
</li>
<li class="">
<p>The AWS Region: us-gov-west-1</p>
</li>
<li class="">
<p>S3 Bucket Access Key Id and Secret obtained in your S3 service-key credentials</p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="permissions">Permissions<a href="https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/#permissions" class="hash-link" aria-label="Direct link to Permissions" title="Direct link to Permissions" translate="no">​</a></h2>
<p>You will then <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PostgreSQL.S3Import.html#USER_PostgreSQL.S3Import.Credentials" target="_blank" rel="noopener noreferrer" class="">set up permissions on your RDS for PostgreSQL DB instance</a> to allow access to the file on the Amazon S3 bucket using the previously obtained credentials.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="importing-data">Importing data<a href="https://docs.cloud.gov/knowledge-base/2023/02/13/Connecting-PostgreSQL-RDS-instance-to-S3/#importing-data" class="hash-link" aria-label="Direct link to Importing data" title="Direct link to Importing data" translate="no">​</a></h2>
<p>Finally you should be able to import the data into the table you have selected by issuing the <code>aws_s3.table_import_from_s3</code> function as described <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PostgreSQL.S3Import.html#USER_PostgreSQL.S3Import.FileFormats" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Encryption in transit on Cloud.gov]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2022/11/04/Encryption-In-Transit/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2022/11/04/Encryption-In-Transit/</guid>
            <pubDate>Fri, 04 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Application to services]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-to-services">Application to services<a href="https://docs.cloud.gov/knowledge-base/2022/11/04/Encryption-In-Transit/#application-to-services" class="hash-link" aria-label="Direct link to Application to services" title="Direct link to Application to services" translate="no">​</a></h2>
<p>The status of encryption in transit between a customer application and <a class="" href="https://docs.cloud.gov/platform/services/intro/">a service instance</a> is dependent on the service. Traffic from applications to ElastiCache and ElasticSearch has TLS enabled by default. The same is true for traffic to S3 as long as you are not using a public bucket in web server mode. For traffic to RDS databases, TLS is enabled but not enforced by default. Customers can require TLS in the code library that they are using to make connections to the RDS database.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-to-application">Application to application<a href="https://docs.cloud.gov/knowledge-base/2022/11/04/Encryption-In-Transit/#application-to-application" class="hash-link" aria-label="Direct link to Application to application" title="Direct link to Application to application" translate="no">​</a></h2>
<p>While traffic between customer applications is not secured with TLS by default, customers can enable <a href="https://www.cloudfoundry.org/blog/secure-container-networking-with-tls/" target="_blank" rel="noopener noreferrer" class="">secure container networking with TLS</a> between their applications on <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#internal-routes" target="_blank" rel="noopener noreferrer" class="">internal routes</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="inbound-traffic-to-applications">Inbound traffic to applications<a href="https://docs.cloud.gov/knowledge-base/2022/11/04/Encryption-In-Transit/#inbound-traffic-to-applications" class="hash-link" aria-label="Direct link to Inbound traffic to applications" title="Direct link to Inbound traffic to applications" translate="no">​</a></h2>
<p>All inbound connections to customer applications on Cloud.gov are protected by TLS. As that traffic comes into Cloud.gov, it crosses a few boundaries where in memory it's decrypted for inspection/routing and then encrypted when it leaves that boundary all the way to the customer application endpoint. For further details, see the documentation on our <a class="" href="https://docs.cloud.gov/platform/compliance/domain-security-standards/">SSL/TLS implementation</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fixing certificate validation errors from AWS CLI when using the cg-egress-proxy]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2022/11/04/fixing-certificate-errors-aws-egress-proxy/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2022/11/04/fixing-certificate-errors-aws-egress-proxy/</guid>
            <pubDate>Fri, 04 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[If you are using the cg-egress-proxy to restrict the egress traffic for your application, you may experience certificate validation errors which prevent you from interacting with brokered AWS services using the CLI.]]></description>
            <content:encoded><![CDATA[<p>If you are using the <a href="https://github.com/GSA/cg-egress-proxy" target="_blank" rel="noopener noreferrer" class=""><code>cg-egress-proxy</code></a> to restrict the egress traffic for your application, you may experience certificate validation errors which prevent you from <a class="" href="https://docs.cloud.gov/platform/services/s3/#interacting-with-your-s3-bucket-from-outside-cloudgov">interacting with brokered AWS services using the CLI</a>.</p>
<p>The cause of the issue is that AWS CLI is overriding certificates that Cloud.gov provides and preventing the AWS CLI from being able to validate TLS connections, thus causing CLI commands to fail.</p>
<p>To force the AWS CLI to use the system CA cert stores, you can add this environment variable:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">AWS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt</span><br></span></code></pre></div></div>
<p>Environment variables can be set for your application by using a <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#env-block" target="_blank" rel="noopener noreferrer" class="">manifest</a>, the <a href="https://cli.cloudfoundry.org/en-US/v7/set-env.html" target="_blank" rel="noopener noreferrer" class=""><code>cf set-env</code> CLI command</a>, or in the <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/deploy-app.html#profile" target="_blank" rel="noopener noreferrer" class=""><code>.profile</code> file for your application</a>. For applications running custom Docker images, you could also set this environment variable in the <a href="https://docs.docker.com/engine/reference/builder/" target="_blank" rel="noopener noreferrer" class=""><code>Dockerfile</code> for your image</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding users to your sandbox]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2022/08/08/adding-users-to-sandbox/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2022/08/08/adding-users-to-sandbox/</guid>
            <pubDate>Mon, 08 Aug 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[If you would like to add a user to your sandbox org, login to your account via the command line and run:]]></description>
            <content:encoded><![CDATA[<p>If you would like to add a user to your sandbox org, login to your account via the command line and run:</p>
<p><code>cf set-space-role &lt;USERNAME&gt; &lt;ORG&gt; &lt;SPACE&gt; &lt;ROLE&gt;</code></p>
<p>Where:</p>
<ul>
<li class=""><code>USERNAME</code> is the username of the user you want to add</li>
<li class=""><code>ORG</code> is the name of your sandbox org</li>
<li class=""><code>SPACE</code> is the name of the space you want the user to have access to within your org.</li>
<li class=""><code>ROLE</code> is set to one of 'SpaceManager', 'SpaceDeveloper', or 'SpaceAuditor' depending on the level of access you want the user to have.</li>
</ul>
<p>The next time the user logs back in to their account they will be able to see and access the space you assigned them to.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Reducing iteration time by using a custom PostgreSQL broker]]></title>
            <link>https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/</link>
            <guid>https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/</guid>
            <pubDate>Thu, 05 May 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[The Cloud.gov team recently deprecated shared database instance plans.]]></description>
            <content:encoded><![CDATA[<p>The Cloud.gov team <a href="https://cloud.gov/2022/04/25/deprecation-notice/" target="_blank" rel="noopener noreferrer" class="">recently deprecated shared database instance plans</a>.</p>
<p>Unlike dedicated instance plans, which each provision a separate RDS database instance and take a
while to create, shared instance plans re-used the same RDS database instance and created new
databases within the same instance, which completed almost instantly.</p>
<p>You can replicate the behavior of the deprecated shared instance plans using an
open-source service broker known as <a href="https://github.com/blacksmith-community/cf-postgres-tinsmith" target="_blank" rel="noopener noreferrer" class=""><code>postgres-tinsmith</code></a>.</p>
<p>Please note that while this approach has been tested manually, the <code>postgres-tinsmith</code> repo is not
actively maintained by the Cloud.gov team, so this documentation is provided as a <strong>proof-of-concept only and does not offer any guarantees of production-readiness</strong>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-create-a-dedicated-rds-service">1. Create a dedicated RDS service<a href="https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/#1-create-a-dedicated-rds-service" class="hash-link" aria-label="Direct link to 1. Create a dedicated RDS service" title="Direct link to 1. Create a dedicated RDS service" translate="no">​</a></h2>
<p>View our available dedicated RDS instance plans for PostgreSQL:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf marketplace -e aws-rds</span><br></span></code></pre></div></div>
<p>Create a PostgreSQL service using one of the dedicated instance plans. For example:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf create-service aws-rds micro-psql &lt;dedicated-db-name&gt;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-deploy-and-configure-postgres-tinsmith">2. Deploy and configure <code>postgres-tinsmith</code><a href="https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/#2-deploy-and-configure-postgres-tinsmith" class="hash-link" aria-label="Direct link to 2-deploy-and-configure-postgres-tinsmith" title="Direct link to 2-deploy-and-configure-postgres-tinsmith" translate="no">​</a></h2>
<p>Follow <a href="https://github.com/blacksmith-community/cf-postgres-tinsmith" target="_blank" rel="noopener noreferrer" class="">the instructions in the repo README</a> to create and configure the <code>postgres-tinsmith</code> service broker.</p>
<p>Make sure to use the <code>&lt;dedicated-db-name&gt;</code> created in step 1 as the database service name to bind to
<code>postgres-tinsmith</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-create-a-database">3. Create a database<a href="https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/#3-create-a-database" class="hash-link" aria-label="Direct link to 3. Create a database" title="Direct link to 3. Create a database" translate="no">​</a></h2>
<p>Once <code>postgres-tinsmith</code> is deployed and configured, create a database using the new <code>shared</code> plan of the
<code>postgres</code> service:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf create-service postgres shared &lt;db-name&gt;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-bind-database-to-your-application">4. Bind database to your application<a href="https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/#4-bind-database-to-your-application" class="hash-link" aria-label="Direct link to 4. Bind database to your application" title="Direct link to 4. Bind database to your application" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cf bind-service &lt;application-name&gt; &lt;db-name&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cf restage &lt;application-name&gt;</span><br></span></code></pre></div></div>
<p>Alternately, you can <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#services-block" target="_blank" rel="noopener noreferrer" class="">bind the database service to your application using a <code>manifest.yml</code> file</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="verifying-your-bound-database-service">Verifying your bound database service<a href="https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/#verifying-your-bound-database-service" class="hash-link" aria-label="Direct link to Verifying your bound database service" title="Direct link to Verifying your bound database service" translate="no">​</a></h3>
<p>Running <code>cf env &lt;application&gt;</code> (e.g. <code>cf env postgres-example-app</code>) should show information about the
bound <code>&lt;db-name&gt;</code> in the <code>VCAP_SERVICES</code> environment variable. See the <a href="https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES" target="_blank" rel="noopener noreferrer" class="">CloudFoundry
documentation for more information about <code>VCAP_SERVICES</code></a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-use-the-database-in-your-application">5. Use the database in your application<a href="https://docs.cloud.gov/knowledge-base/2022/05/05/creating-postgresql-databases-from-shared-rds/#5-use-the-database-in-your-application" class="hash-link" aria-label="Direct link to 5. Use the database in your application" title="Direct link to 5. Use the database in your application" translate="no">​</a></h2>
<p>Make sure that your application properly reads and implements the credentials for the database from
the <code>VCAP_SERVICES</code> environment variable.</p>]]></content:encoded>
        </item>
    </channel>
</rss>