<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://mehmandarov.com/tag/cloud/feed.xml" rel="self" type="application/atom+xml"/><link href="https://mehmandarov.com/tag/cloud/" rel="alternate" type="text/html"/><updated>2023-10-17T15:50:00+02:00</updated><id>https://mehmandarov.com/tag/cloud/feed.xml</id><title type="html">Rustam Mehmandarov - tag: cloud</title><subtitle type="text">Posts tagged &quot;cloud&quot; on Rustam Mehmandarov.</subtitle><author><name>Rustam Mehmandarov</name></author><entry><title type="html">Cloud Security Principles: Part 2</title><link href="https://mehmandarov.com/cloud-security-principles-2/" rel="alternate" type="text/html" title="Cloud Security Principles: Part 2"/><published>2023-10-17T15:50:00+02:00</published><updated>2023-10-17T15:50:00+02:00</updated><id>https://mehmandarov.com/cloud-security-principles-2</id><content type="html" xml:base="https://mehmandarov.com/cloud-security-principles-2/"><![CDATA[<p><em>This is the second part of the series on the Cloud Security Principles. This post will look at some key principles for securing your applications. Similarly to the <a href="/cloud-security-principles/">first post</a>, some prior knowledge of various IT architecture and security concepts may be expected. This post was inspired by a talk I have recently done with <a href="https://linktr.ee/nehasardana">Neha Sardana</a> at JAX New York.</em></p>

<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#principles">Principles</a></li>
  <li><a href="#conclusion">Conclusion</a></li>
</ul>

<hr />

<h2 id="introduction">Introduction</h2>
<p><a href="/cloud-security-principles/">In the first part</a>, we have summed up all the essential elements to consider when working with Cloud and securing cloud-native applications/platforms. In this post, we would like to give you some concrete principles and tips for creating more secure applications.</p>

<h2 id="principles">Principles</h2>
<h3 id="multi-layered-defense">Multi-Layered Defense</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">general</code></p>

<p>First of all, a more generic but important principle: It would be best to look at security as a whole &#8211; integrating various security layers on multiple levels in any system. It should include cyber-security plans for:</p>

<ol>
  <li>Devices</li>
  <li>Applications</li>
  <li>Networks</li>
  <li>Infrastructure</li>
  <li>People</li>
</ol>

<p>Think of this principle as all the layers of clothing you wear to protect yourself from cold and bad weather. If one of the layers is compromised, there is always another to keep you warm and dry.</p>

<h3 id="identity-and-access-management-iam-misconfiguration">Identity and Access Management (IAM) Misconfiguration</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">network</code>, <code class="language-plaintext highlighter-rouge">permissions</code></p>

<p>You need to control access and permissions meticulously and over time.
Things to consider:</p>
<ul>
  <li>Implementing role-based access control (RBAC)</li>
  <li>Principle of least privilege</li>
  <li>Routines for updating and removing permissions when they are no longer needed.</li>
  <li>Explore possibilities for using time-based conditions for IAM policies.</li>
</ul>

<h3 id="api-security">API Security</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">endpoints</code>, <code class="language-plaintext highlighter-rouge">permissions</code></p>

<ul>
  <li>APIs act as the gateways to your application and data. Securing access to and securing them from known vulnerabilities is paramount to prevent unauthorized access and data breaches.</li>
  <li>Utilize <em>authentication</em>, <em>authorization</em>, and <em>API gateways</em> to control access and protect sensitive information. Don&#8217;t forget to monitor the software or libraries that make APIs available (e.g., runtimes, middleware)</li>
</ul>

<h3 id="data-encryption">Data Encryption</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">data</code></p>

<ul>
  <li>Safeguarding data at rest, in transit, and during processing is critical for your applications.</li>
  <li>Utilize encryption, tokenization, and data masking techniques to ensure data protection. Removing unnecessary sensitive information can simplify some of these tasks.</li>
  <li>If a platform or a Cloud provider provides the encryption, consider if you would like to use the standard keys for encryption or &#8220;bring your own&#8221; and manage them yourself or through a third party.</li>
  <li>Beware: Don&#8217;t write your own crypto! Ever.</li>
</ul>

<h3 id="zero-trust">Zero Trust</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">network</code>, <code class="language-plaintext highlighter-rouge">permissions</code></p>

<ul>
  <li>The Zero Trust security model assumes that no one is inherently trustworthy, even those within your network.</li>
  <li>This is opposed to more traditional approaches where perimeter security was prioritized over security inside the network.</li>
  <li>Adopting this approach, every request, user, and device is thoroughly verified before gaining access.</li>
  <li>Again: Implement the principle of least privilege, where users are only granted the minimum level of access required to perform their tasks.</li>
</ul>

<h3 id="software-supply-chain-security">Software Supply Chain Security</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">software</code>, <code class="language-plaintext highlighter-rouge">environment</code></p>

<ul>
  <li>Create <a href="https://www.cisa.gov/sbom">Software Bill of Materials (SBOM)</a> for your software</li>
  <li>Governance: Know where all the building blocks (artifacts) of your software are coming from.</li>
  <li>Automate security checks within your CI/CD pipeline to catch vulnerabilities early and often.</li>
  <li>Use static code analysis with tools like SonarQube to scan your code for potential security flaws and integrate those checks into your CI/CD pipeline to ensure continuous security monitoring.</li>
  <li>Use tools to monitor not only the code you develop yourself but also all the third-party libraries you utilize in your code.</li>
  <li>With DevSecOps, automated security security is becoming integral to the development process. Adopt it if you haven&#8217;t done so already.</li>
</ul>

<h3 id="secure-containerization">Secure Containerization</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">software</code>, <code class="language-plaintext highlighter-rouge">environment</code></p>

<ul>
  <li>Containerization and orchestration technologies, like Docker and Kubernetes, offer exceptional flexibility but also introduce security concerns.</li>
  <li>Securing containers and managing their lifecycle is vital to ensure a safe cloud environment.</li>
  <li>For example, use container scanning tools to identify vulnerabilities within container images before deploying them.</li>
  <li>Additionally, enforce strict security policies and segregate workloads using Kubernetes namespaces.</li>
</ul>

<h3 id="continuous-monitoring-and-incident-response">Continuous Monitoring and Incident Response</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">software</code>, <code class="language-plaintext highlighter-rouge">environment</code></p>

<ul>
  <li>The cloud landscape is constantly changing, and threats evolve rapidly. This means that we need to monitor not only for known threats but also for anomalies.</li>
  <li>Continuous monitoring and proactive incident response are essential to detect anomalies and respond swiftly to security incidents.</li>
  <li>For example, use cloud-native monitoring tools your Cloud or platform provider provides.</li>
  <li>Have good logging, but remember that more is not always better &#8211; log relevant information.</li>
</ul>

<h3 id="human-factors-including-social-engineering-misconfigurations-and-human-errors">Human Factors (including Social Engineering, Misconfigurations, and Human Errors)</h3>
<p><em><strong>Keywords</strong></em>: <code class="language-plaintext highlighter-rouge">people</code>, <code class="language-plaintext highlighter-rouge">human factors</code></p>

<ul>
  <li>82% of incidents are caused by human factors (<a href="https://www.verizon.com/business/resources/T39a/reports/dbir/2022-data-breach-investigations-report-dbir.pdf">2022 Data Breach Investigations Report</a>)</li>
  <li>Creating secure applications also implies providing security training for the system users.</li>
  <li>Social engineering and human factor has proven to be essential to creating secure applications.</li>
  <li>Consider running security awareness campaigns and employee training from user and developer perspectives.</li>
  <li>Automate routine and mundane tasks &#8211; humans often don&#8217;t enjoy carrying out tasks like this and are prone to errors; computers, on the other hand, excel at tasks like this!</li>
</ul>

<h2 id="conclusion">Conclusion</h2>
<p>You have probably heard that nothing is stronger than its weakest link. Therefore, it is important to look at various sides of the security. Especially in the Cloud, one size does not fit all when it comes to security. Cloud platforms, software, and threats constantly evolve and add to the complexity of creating secure applications.</p>

<p>Here, we have seen some of the principles to consider regarding the security of the platforms and application development for the Cloud and cloud-native applications in general.</p>

<p>Finally, note that this is not an exhaustive list but is instead meant to serve as a stepping stone to more secure application development.</p>

<hr />]]></content><author><name>Rustam Mehmandarov</name></author><summary type="html">This is the second part of the series on the Cloud Security Principles. This post will look at some key principles for securing your applications. Similarly to the first post, some prior knowledge of various IT architecture and security concepts may be expected. This post was inspired by a talk I...</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mehmandarov.com/assets/images/posts-images/container-ship.jpeg"/><category term="blog"/><category term="english"/><category term="architecture"/><category term="security"/><category term="cloud"/></entry><entry><title type="html">Cloud Security Principles</title><link href="https://mehmandarov.com/cloud-security-principles/" rel="alternate" type="text/html" title="Cloud Security Principles"/><published>2023-10-12T09:50:00+02:00</published><updated>2023-10-12T09:50:00+02:00</updated><id>https://mehmandarov.com/cloud-security-principles</id><content type="html" xml:base="https://mehmandarov.com/cloud-security-principles/"><![CDATA[<p><em>This post was inspired by a talk I have recently done with <a href="https://linktr.ee/nehasardana">Neha Sardana</a> at JAX New York and is meant to serve as a stepping stone to categorize and catalog the things you need to consider working with the Cloud and Cloud-native applications. Some prior knowledge of various concepts within IT architecture and security may be expected for this post.</em></p>

<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#key-elements-of-a-cloud-security-architecture">Key Elements of a Cloud Security Architecture</a></li>
  <li><a href="#responsibilities">Responsibilities</a></li>
  <li><a href="#constantly-evolving-landscape">Constantly Evolving Landscape</a></li>
  <li><a href="#platform-security-architecture">Platform Security Architecture</a></li>
  <li><a href="#application-security-architecture">Application Security Architecture</a></li>
  <li><a href="#conclusion">Conclusion</a></li>
</ul>

<hr />

<h2 id="introduction">Introduction</h2>
<p>Whether you are running on the Cloud or not it is all about the <a href="https://www.techtarget.com/whatis/definition/Confidentiality-integrity-and-availability-CIA">CIA triad model</a> &#8211; Confidentiality, Integrity, and Availability.</p>

<p>When thinking about Cloud Security Architecture we need to be able to think about the whole stack. Of course, we don&#8217;t need to think about all the moving parts alone &#8211; it is a shared responsibility between the Cloud service provider and you, the user of the platform.</p>

<h2 id="key-elements-of-a-cloud-security-architecture">Key Elements of a Cloud Security Architecture</h2>
<p>Let&#8217;s first start by defining the key elements of a Cloud Security Architecture, divided across the layers of the stack, based on the Cloud Security Alliance (CSA) stack model.</p>

<p><img src="/assets/images/posts-images/2023-10-12-fig1.png" alt="Fig.1: Cloud Security Alliance (CSA) stack model" /></p>
<figcaption class="caption">Fig.1: Cloud Security Alliance (CSA) stack model</figcaption>

<p>Now, we can also mention some of the main challenges related to security, divided into separate groups, and try to map them to the CIA triad model that we have mentioned earlier.</p>

<h3 id="network-and-storage">Network and Storage</h3>
<ul>
  <li>Data Encryption</li>
  <li>Network Security</li>
</ul>

<h3 id="application-layer">Application layer</h3>
<ul>
  <li>Application Security</li>
  <li>Logging and Monitoring</li>
  <li>Identity and Access Management (IAM)</li>
</ul>

<h3 id="observability-and-traceability">Observability, and traceability</h3>
<ul>
  <li>Incident Response and Recovery</li>
  <li>Vendor and Third-Party Risk Management</li>
</ul>

<h3 id="devops">DevOps</h3>
<ul>
  <li>Automation and Orchestration</li>
  <li>Resilience and High Availability</li>
</ul>

<h3 id="general">General</h3>
<ul>
  <li>Compliance and Governance</li>
  <li>User Training and Awareness</li>
  <li>Cloud Provider Security Features</li>
</ul>

<p><img src="/assets/images/posts-images/2023-10-12-fig2.png" alt="Fig.2: Challenges of Cloud Security" /></p>
<figcaption class="caption">Fig.2: Challenges of Cloud Security</figcaption>

<h2 id="responsibilities">Responsibilities</h2>
<h3 id="shared-responsibility--intersection-of-responsibilities">Shared Responsibility + Intersection of Responsibilities</h3>
<p>Addressing all these challenges is a shared responsibility between the Cloud service provider and the customer and the division will vary depending on the type of the solution and whether you are using IaaS, PaaS, or SaaS.</p>

<p>Typically, Cloud service providers will take care of the lower parts of the stack, like physical, infrastructure, and platform security, while customers will be responsible for creating secure applications, securing their data, creating proper Identity and Access Management (IAM), and configuration management.</p>

<p>An effective overlap and a clear understanding of the responsibilities ensure comprehensive security coverage across all layers.</p>

<p><img src="/assets/images/posts-images/2023-10-12-fig3.png" alt="Fig.3: Shared security responsibility between the Cloud Service providers and the Customers" /></p>
<figcaption class="caption">Fig.3: Shared security responsibility between the Cloud Service providers and the Customers</figcaption>

<h2 id="constantly-evolving-landscape">Constantly Evolving Landscape</h2>
<h3 id="evolving-landscape--constant-change">Evolving Landscape == Constant Change</h3>
<p>One of the differentiating factors from regular application development is the constant change and evolution of the platform and tooling on one side, and the constantly evolving types of attacks and possibly larger attack surfaces on the other side.</p>

<p>These factors will lead to changes in the model and the responsibility division. The same might be influenced by the new services being introduced both from the side of the Cloud service provider and the customer (app developer).</p>

<p>Therefore, regular communication between the parties involved and staying updated on their security practices is essential to ensure secure Cloud applications.</p>

<h2 id="types-of-the-cloud-security-architecture">Types of the Cloud Security Architecture</h2>
<p>The Cloud Security Architecture is <em>twofold</em> &#8211; you will need to choose a <em>platform</em> for running your application and think about the security of the <em>application</em> you will be deploying on that platform.</p>

<h3 id="platform-security-architecture">Platform Security Architecture</h3>
<p>Let&#8217;s start with defining the types of platforms and list some of the key elements to consider when choosing a platform type.</p>

<h4 id="public-cloud-security-architecture">Public Cloud Security Architecture</h4>
<ul>
  <li>Designed for cloud services provided by third-party vendors (e.g., AWS, Azure, Google Cloud).</li>
  <li>Focuses on securing data and applications hosted on shared infrastructure.</li>
  <li>Utilizes the security features provided by the cloud service provider (CSP) while also implementing * additional security measures.</li>
  <li>Emphasizes network segmentation, encryption, IAM, and monitoring.</li>
</ul>

<h4 id="private-cloud-security-architecture">Private Cloud Security Architecture</h4>
<ul>
  <li>Created for cloud environments dedicated to a single organization.</li>
  <li>Offers more control over security settings and configurations.</li>
  <li>Often used by organizations with strict compliance requirements or sensitive data.</li>
  <li>Implements strong access controls, encryption, and strict network isolation.</li>
</ul>

<h4 id="hybrid-cloud-security-architecture">Hybrid Cloud Security Architecture</h4>
<ul>
  <li>Combines public and private clouds to take advantage of the benefits of both deployment models</li>
  <li>Security architecture addresses integration challenges and ensures consistency across environments</li>
  <li>Emphasizes secure communication between on-premises and cloud components</li>
  <li>Requires seamless identity and access management across both environments</li>
</ul>

<h4 id="multi-cloud-security-architecture">Multi-Cloud Security Architecture</h4>
<ul>
  <li>Involves using services from multiple cloud providers simultaneously</li>
  <li>Ensures compatibility and security across diverse cloud platforms</li>
  <li>Requires careful management of authentication, authorization, data protection, and compliance measures</li>
  <li>Aims to prevent vendor lock-in and distribute risk</li>
</ul>

<h3 id="application-security-architecture">Application Security Architecture</h3>
<p>Here are some things you will need to think about when developing modern applications for the Cloud and the cloud-native world.</p>

<h4 id="1-secure-your-code">1. Secure Your Code</h4>
<ul>
  <li>Software Supply Chain Security: Securing and monitoring your artifacts and third-party libraries.</li>
  <li>Making sure the code you have written is secure: OWASP Top 10, static code analysis, coding best practices.</li>
</ul>

<h4 id="2-your-container-and-serverless-security-architecture">2. Your Container (and Serverless) Security Architecture</h4>
<ul>
  <li>Specifically addresses security for containerized applications (e.g., Containers, Kubernetes) and serverless computing (e.g., AWS Lambda, Azure Functions, Cloud Functions, or Cloud Run on Google Cloud)</li>
  <li>Focus on securing microservices, communication between them, their orchestrators, and function-as-a-service (FaaS) platforms</li>
  <li>Involves isolating containers, securing images, and managing runtime security</li>
</ul>

<h4 id="3-add-devsecops-architecture-practices">3. Add DevSecOps Architecture Practices</h4>
<ul>
  <li>Integrate security practices into the DevOps process: DevSecOps</li>
  <li>Ensure security is considered at every stage of application development and deployment</li>
  <li>Involves automated security testing, vulnerability scanning, and security policy enforcement</li>
</ul>

<h4 id="4-cross-application-and-cross-container-communication-zero-trust-security-architecture">4. Cross-application and Cross-container communication: Zero Trust Security Architecture</h4>
<ul>
  <li>Assume no trust by default and require strict authentication and authorization for all users and devices</li>
  <li>Focus on identity verification, principle of least privilege, and continuous monitoring</li>
  <li>Suitable for cloud environments where traditional perimeter defenses are less effective</li>
</ul>

<h4 id="5-physical-security-edge-cloud-security-architecture">5. Physical security: Edge Cloud Security Architecture</h4>
<ul>
  <li>Address security concerns at the edge of the network, closer to where data is generated and consumed</li>
  <li>In case of having local edge hardware devices consider also physical security of those devices</li>
  <li>Involves considerations like local processing, secure communication, and protection against threats targeting edge devices</li>
</ul>

<h4 id="6-compliance-centric-security-architecture">6. Compliance-Centric Security Architecture</h4>
<ul>
  <li>Tailored to meet specific regulatory compliance requirements (e.g., GDPR, HIPAA, PCI DSS)</li>
  <li>Focus on implementing controls and safeguards to adhere to relevant standards</li>
</ul>

<h2 id="conclusion">Conclusion</h2>
<p>We have seen the key elements of the cloud security architecture and the building blocks of the whole stack. Furthermore, we have looked at the various types and elements to consider when it comes to the security of the platforms and application development. This is a stepping stone to categorize and group some of the main things you will need to consider when working with the Cloud and cloud-native applications.</p>

<hr />
<p><em>** Illustrations in this post: Rustam Mehmandarov.</em></p>

<hr />]]></content><author><name>Rustam Mehmandarov</name></author><summary type="html">This post was inspired by a talk I have recently done with Neha Sardana at JAX New York and is meant to serve as a stepping stone to categorize and catalog the things you need to consider working with the Cloud and Cloud-native applications. Some prior knowledge of various concepts within IT arch...</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mehmandarov.com/assets/images/posts-images/containers.jpg"/><category term="blog"/><category term="english"/><category term="architecture"/><category term="security"/><category term="cloud"/></entry><entry><title type="html">Configuring Slack Notifications for Google Cloud Build</title><link href="https://mehmandarov.com/slack-notifications-for-cloud-build/" rel="alternate" type="text/html" title="Configuring Slack Notifications for Google Cloud Build"/><published>2019-03-01T07:01:00+01:00</published><updated>2019-03-01T07:01:00+01:00</updated><id>https://mehmandarov.com/slack-notifications-for-cloud-build</id><content type="html" xml:base="https://mehmandarov.com/slack-notifications-for-cloud-build/"><![CDATA[<p><em>Adding Slack notifications for your Google Cloud Build jobs explained with code examples and screenshots.</em></p>

<ul>
  <li><a href="#intro">Intro</a></li>
  <li><a href="#1-before-you-begin">1. Before you begin</a></li>
  <li><a href="#2-create-a-cloud-function">2. Create a Cloud Function</a></li>
  <li><a href="#3-deploy-the-cloud-function">3. Deploy the Cloud Function</a></li>
</ul>

<hr />

<h2 id="intro">Intro</h2>

<p>Recently we decided to migrate our builds from Travis CI to Google Cloud Build to speed up the builds. The process was quite easy and flawless; however, we were still missing a few minor things. One of them was the notifications from Cloud Build to our <code class="language-plaintext highlighter-rouge">#ops</code> channel in Slack. This was slightly annoying because you would not know if the build was finished and the site was deployed, or if it failed for some reason.</p>

<p>Integrating with Cloud Build was a bit more different than what you are used to from integrations with Jenkins or Travis CI. Normally you would just create a webhook that would call an interface in the Slack API. In Cloud Build, on the other hand, everything is getting posted to the Pub/Sub queue built into the platform, and here you would just need to subscribe to the specific queue and listen for the events. To achieve the latter, you would need a small serverless function to listen for these events and to call the Slack API.</p>

<p><img src="/assets/images/posts-images/2019-03-01-architecture.png" alt="The Architecture" class="bigger-image" /></p>
<figcaption class="caption">The Architecture.</figcaption>
<p><br /></p>

<p>Note that here we will, technically, be using paid services on Google Cloud Platform, as both Cloud Build, Cloud Pub/Sub, and Cloud Functions are billable components. However, since all the components above provide a generous free tier, you will need to work hard to get passed the free tier with this setup.</p>

<ul>
  <li><strong>Cloud Build:</strong> Free first 120 builds-minutes per day for <code class="language-plaintext highlighter-rouge">Basic</code> machine type (<code class="language-plaintext highlighter-rouge">n1-standard-1</code>).</li>
  <li><strong>Cloud Pub/Sub:</strong> Free first 10GB per month (<a href="https://cloud.google.com/pubsub/pricing">pricing</a>).</li>
  <li><strong>Cloud Functions:</strong> Free first 2 million invocations per month (<a href="https://cloud.google.com/functions/pricing">pricing</a>).</li>
</ul>

<h2 id="1-before-you-begin">1. Before you begin</h2>

<h3 id="11-prepare-your-gcp-project">1.1 Prepare your GCP project</h3>

<p><em>I assume you have a Google Cloud Account, and that you have signed in to your account.</em></p>

<ol>
  <li>Select or create a Google Cloud Platform project, e.g. from the <a href="https://console.cloud.google.com/cloud-resource-manager">Manage resources page</a>.</li>
  <li>Make sure that <a href="https://cloud.google.com/billing/docs/how-to/modify-project">billing is enabled</a> for your Google Cloud Platform project.</li>
  <li>Enable the Cloud Functions and Cloud Pub/Sub. You can also enable the APIs using this <a href="https://console.cloud.google.com/flows/enableapi?apiid=cloudfunctions,pubsub">link</a>.</li>
  <li>Use <a href="https://cloud.google.com/shell/docs/quickstart">Cloud Shell</a> right from the browser, or you can <a href="https://cloud.google.com/sdk/docs/">Install and initialize the Cloud SDK</a> on your own machine.</li>
  <li>If you have installed the Cloud SDK, update and install gcloud components:</li>
</ol>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gcloud components update <span class="o">&amp;&amp;</span>
gcloud components <span class="nb">install </span>alpha beta</code></pre></figure>

<h3 id="12-prepare-your-slack-app">1.2 Prepare your Slack App</h3>

<p><em>I assume you have Slack installed and that you have created and signed-in to your account.</em></p>

<p>Create a <a href="https://api.slack.com/apps?new_app=1">new Slack app</a>:</p>

<ol>
  <li>Choose the app&#8217;s name and your Slack team. Click Create.</li>
  <li>Click Incoming Webhooks.</li>
  <li>Activate incoming webhooks.</li>
  <li>Click Add New Webhook to Workspace. An authorization page opens.</li>
  <li>From the drop-down menu, select the channel to which you would like notifications sent.</li>
  <li>Click Authorize.</li>
  <li>A webhook for your Slack application has been created. Copy the webhook URL and save it for later use.</li>
</ol>

<h2 id="2-create-a-cloud-function">2. Create a Cloud Function</h2>

<p>We need to create a Cloud Storage bucket to stage your Cloud Functions files. Use <code class="language-plaintext highlighter-rouge">[STAGING_BUCKET_NAME]</code> that is a globally-unique bucket name (such as <code class="language-plaintext highlighter-rouge">[PROJECT-ID]_cloudbuilds</code>):</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gsutil mb gs://[STAGING_BUCKET_NAME]</code></pre></figure>

<p>You should see the following output:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">Creating gs://[PROJECT-ID]_cloudbuilds/[STAGING_BUCKET_NAME]...</code></pre></figure>

<p>Next, create a directory on your local system for the application code:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">mkdir</span> ~/gcb_slack
<span class="nb">cd</span> ~/gcb_slack</code></pre></figure>

<p>Then, create the following two files in the <code class="language-plaintext highlighter-rouge">gcb_slack</code> directory.</p>

<p><strong>File 1:</strong> <code class="language-plaintext highlighter-rouge">package.json</code></p>

<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"google-container-slack"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.0.1"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Slack integration for Google Cloud Build, using Google Cloud Functions"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"main"</span><span class="p">:</span><span class="w"> </span><span class="s2">"index.js"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"dependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"@slack/client"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4.10.0"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span></code></pre></figure>

<p><strong>File 2:</strong> <code class="language-plaintext highlighter-rouge">index.js</code></p>

<p><em>Note: Make sure to update <code class="language-plaintext highlighter-rouge">SLACK_WEBHOOK_URL</code> in the code below.</em></p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">const</span> <span class="nx">IncomingWebhook</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">@slack/client</span><span class="dl">'</span><span class="p">).</span><span class="nx">IncomingWebhook</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">SLACK_WEBHOOK_URL</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">&lt;INSERT YOUR WEBHOOK FROM STEP 1.2&gt;</span><span class="dl">"</span>

<span class="kd">const</span> <span class="nx">webhook</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">IncomingWebhook</span><span class="p">(</span><span class="nx">SLACK_WEBHOOK_URL</span><span class="p">);</span>

<span class="c1">// subscribe is the main function called by Cloud Functions.</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">subscribe</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
 <span class="kd">const</span> <span class="nx">build</span> <span class="o">=</span> <span class="nf">eventToBuild</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>

  <span class="c1">// Skip if the current status is not in the status list.</span>
  <span class="c1">// Add additional statues to list if you'd like:</span>
  <span class="c1">// QUEUED, WORKING, SUCCESS, FAILURE,</span>
  <span class="c1">// INTERNAL_ERROR, TIMEOUT, CANCELLED</span>
  <span class="kd">const</span> <span class="nx">status</span> <span class="o">=</span> <span class="p">[</span><span class="dl">'</span><span class="s1">SUCCESS</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">FAILURE</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">INTERNAL_ERROR</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">TIMEOUT</span><span class="dl">'</span><span class="p">];</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">status</span><span class="p">.</span><span class="nf">indexOf</span><span class="p">(</span><span class="nx">build</span><span class="p">.</span><span class="nx">status</span><span class="p">)</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nf">callback</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="c1">// Send message to Slack.</span>
  <span class="kd">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="nf">createSlackMessage</span><span class="p">(</span><span class="nx">build</span><span class="p">);</span>
  <span class="nx">webhook</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">callback</span><span class="p">);</span>
<span class="p">};</span>

<span class="c1">// eventToBuild transforms pubsub event message to a build object.</span>
<span class="kd">const</span> <span class="nx">eventToBuild</span> <span class="o">=</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="k">new</span> <span class="nc">Buffer</span><span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="dl">'</span><span class="s1">base64</span><span class="dl">'</span><span class="p">).</span><span class="nf">toString</span><span class="p">());</span>
<span class="p">}</span>

<span class="c1">// createSlackMessage create a message from a build object.</span>
<span class="kd">const</span> <span class="nx">createSlackMessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">build</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">message</span> <span class="o">=</span> <span class="p">{</span>
   <span class="na">text</span><span class="p">:</span> <span class="s2">`Build </span><span class="se">\`</span><span class="p">${</span><span class="nx">build</span><span class="p">.</span><span class="nx">id</span><span class="p">}</span><span class="se">\`</span><span class="s2">`</span><span class="p">,</span>
    <span class="na">mrkdwn</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="na">attachments</span><span class="p">:</span> <span class="p">[</span>
      <span class="p">{</span>
        <span class="na">title</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Build logs - Your Custom Message Goes Here</span><span class="dl">'</span><span class="p">,</span>
        <span class="na">title_link</span><span class="p">:</span> <span class="nx">build</span><span class="p">.</span><span class="nx">logUrl</span><span class="p">,</span>
        <span class="na">fields</span><span class="p">:</span> <span class="p">[{</span>
          <span class="na">title</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Status</span><span class="dl">'</span><span class="p">,</span>
          <span class="na">value</span><span class="p">:</span> <span class="nx">build</span><span class="p">.</span><span class="nx">status</span>
        <span class="p">}]</span>
      <span class="p">}</span>
    <span class="p">]</span>
  <span class="p">};</span>
  <span class="k">return</span> <span class="nx">message</span>
<span class="p">}</span></code></pre></figure>

<h2 id="3-deploy-the-cloud-function">3. Deploy the Cloud Function</h2>

<p>To deploy the subscribe function with a Cloud Pub/Sub trigger, run the following command in the <code class="language-plaintext highlighter-rouge">gcb_slack</code> directory:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">gcloud functions deploy subscribe <span class="nt">--stage-bucket</span> <span class="o">[</span>STAGING_BUCKET_NAME] <span class="se">\</span>
    <span class="nt">--trigger-topic</span> cloud-builds</code></pre></figure>

<p>where <code class="language-plaintext highlighter-rouge">[STAGING_BUCKET_NAME]</code> is the name of your staging Cloud Storage Bucket that you defined earlier.</p>

<p>You should see an output confirming the creation of the cloud function and <code class="language-plaintext highlighter-rouge">status: READY</code>.</p>

<p>After you&#8217;ve completed deployment of the Cloud Function, when a build event occurs, you will receive a Slack notification.</p>

<p><img src="/assets/images/posts-images/2019-03-01-slack-app.png" alt="The Slack App in action" /></p>
<figcaption class="caption">The Slack App in action.</figcaption>
<p><br /></p>

<p>Also, feel free to customize your app, like adding a custom icon, as I did with mine. &#9757;&#65039;</p>

<hr />]]></content><author><name>Rustam Mehmandarov</name></author><summary type="html">Setting up Slack notifications for Google Cloud Build jobs with code examples and screenshots.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mehmandarov.com/assets/images/posts-images/lego-bots.jpg"/><category term="blog"/><category term="field notes"/><category term="automation"/><category term="cloud"/><category term="english"/></entry><entry><title type="html">Automating Confluence Posts with Amazon Cloud (AWS)</title><link href="https://mehmandarov.com/confluence-and-aws/" rel="alternate" type="text/html" title="Automating Confluence Posts with Amazon Cloud (AWS)"/><published>2017-01-29T09:26:00+01:00</published><updated>2017-01-29T09:26:00+01:00</updated><id>https://mehmandarov.com/confluence-and-aws</id><content type="html" xml:base="https://mehmandarov.com/confluence-and-aws/"><![CDATA[<p><em>How do you automate a job without setting up a dedicated machine?</em></p>

<ul>
  <li><a href="#posting-via-confluence-rest-api">Posting via Confluence REST API</a></li>
  <li><a href="#creating-a-lambda-function-in-aws">Creating a Lambda Function in AWS</a></li>
  <li><a href="#schedule-it">Schedule it!</a></li>
</ul>

<hr />

<p>Some mundane tasks can easily be automated. In my case, I needed something that could post to our Confluence instance at a specific time every week. This is because we use blog posts in Confluence for announcing our weekly volunteer meetings and as a simple attendance management.</p>

<hr />

<h2 id="posting-via-confluence-rest-api">Posting via Confluence REST API</h2>

<p><a href="https://en.wikipedia.org/wiki/Confluence_(software)" target="_blank">Confluence</a>, a team collaboration software written in Java and quite often used in corporate environments, offers a <a href="https://developer.atlassian.com/confdev/confluence-server-rest-api/confluence-rest-api-examples" target="_blank">REST API</a> that makes it possible to perform many operations on the content. In this case, I was interested in posting new content with some text, and I was getting tired of doing that manually every week. So, I thought: <a href="https://xkcd.com/1319/" target="_blank">&#8220;I spend a lot of time on this task. I should write a program automating it!&#8221;</a>.</p>

<p>The first take on that problem was a simple Python script:</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="n">json</span>
<span class="kn">import</span> <span class="n">requests</span>

<span class="n">url</span> <span class="o">=</span> <span class="sh">"</span><span class="s">https://some-confluence-url.com/rest/api/content/</span><span class="sh">"</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span> <span class="sh">"</span><span class="s">content-type</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">application/json</span><span class="sh">"</span> <span class="p">}</span>
<span class="n">payload</span> <span class="o">=</span> <span class="p">{</span> <span class="sh">"</span><span class="s">type</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">blogpost</span><span class="sh">"</span><span class="p">,</span>
            <span class="sh">"</span><span class="s">title</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">Fancy meeting title</span><span class="sh">"</span><span class="p">,</span>
            <span class="sh">"</span><span class="s">space</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
                <span class="sh">"</span><span class="s">key</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">mySpaceNameGoesHere</span><span class="sh">"</span>
            <span class="p">},</span>
            <span class="sh">"</span><span class="s">body</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
                <span class="sh">"</span><span class="s">storage</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
                    <span class="sh">"</span><span class="s">representation</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">storage</span><span class="sh">"</span><span class="p">,</span>
                    <span class="sh">"</span><span class="s">value</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">Meeting description goes here.</span><span class="sh">"</span>
                <span class="p">}</span>
            <span class="p">}</span>
            <span class="c1">#"history": {
</span>            <span class="c1">#    "createdDate": '2017-01-10T14:00:00.000Z'
</span>            <span class="c1">#},
</span>
        <span class="p">}</span>

<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> 
                         <span class="n">data</span><span class="o">=</span><span class="n">json</span><span class="p">.</span><span class="nf">dumps</span><span class="p">(</span><span class="n">payload</span><span class="p">),</span> 
                         <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> 
                         <span class="n">auth</span><span class="o">=</span><span class="p">(</span><span class="sh">"</span><span class="s">myUserName</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">mySecretPassword</span><span class="sh">"</span><span class="p">))</span>
<span class="k">print</span> <span class="n">json</span><span class="p">.</span><span class="nf">dumps</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="nf">json</span><span class="p">(),</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span></code></pre></figure>

<p>You should be able to run this script against your end-point and post your content. Just note that I used <code class="language-plaintext highlighter-rouge">requests</code> library here that needs to be installed separately, for instance, by using <code class="language-plaintext highlighter-rouge">pip</code>:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>pip <span class="nb">install </span>requests</code></pre></figure>

<p>Also, you will need to update the following values in the script:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">url</code> &#8211; the URL to your site</li>
  <li><code class="language-plaintext highlighter-rouge">type</code> &#8211; can be a <code class="language-plaintext highlighter-rouge">blogpost</code> or a <code class="language-plaintext highlighter-rouge">page</code></li>
  <li><code class="language-plaintext highlighter-rouge">title</code> &#8211;&#160;page or post title</li>
  <li><code class="language-plaintext highlighter-rouge">space</code> &#8211; a Confluence space where the post will belong</li>
  <li><code class="language-plaintext highlighter-rouge">value</code> &#8211; content of the page, can contain HTML tags</li>
  <li><code class="language-plaintext highlighter-rouge">auth</code> &#8211;&#160;username and password (please note that, for security reasons, it might be a good idea to create a separate user with restricted access rights just for posting specific content)</li>
  <li><code class="language-plaintext highlighter-rouge">createdDate</code> &#8211; you can also add the commented-out part to add a specific blog post date</li>
</ul>

<p>The script uses basic authentication to post the content and, if successful, returns metadata about the post as a response. If it fails, the response from Confluence end-point should point you in the right direction.</p>

<hr />

<h2 id="creating-a-lambda-function-in-aws">Creating a Lambda Function in AWS</h2>

<p>Now we are one step closer to automation. The script works, and we can post content with a simple push of a button. What now?</p>

<p>Well, now I needed something to run that script and something to trigger that action. The trigger is the time as I wanted to run our script weekly, but first I needed to deploy our script to the Cloud. Scheduling and triggers would come later.</p>

<p>Since we had some infrastructure on AWS already, I decided to deploy the script on the same platform. I wanted to deploy it as a simple stand-alone function in the Cloud &#8211; in AWS world it is called a <a href="http://docs.aws.amazon.com/lambda/latest/dg/welcome.html" target="_blank">Lambda function</a>.</p>

<p>I started by wrapping our code into a function and making it AWS Lambda function compatible &#8211; to define a function that takes two arguments: <code class="language-plaintext highlighter-rouge">event</code> and <code class="language-plaintext highlighter-rouge">context</code>. I choose to call the function <code class="language-plaintext highlighter-rouge">blogpost_handler</code>:</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c1">#!/usr/bin/python
# -*- coding: utf-8 -*-
</span>
<span class="c1"># File name: poster.py
</span>
<span class="kn">import</span> <span class="n">requests</span>
<span class="kn">import</span> <span class="n">json</span>
<span class="kn">import</span> <span class="n">datetime</span>

<span class="k">def</span> <span class="nf">blogpost_handler</span><span class="p">(</span><span class="n">event</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span> 

    <span class="c1"># Script is run on Sunday, need to use date for Tuesday
</span>    <span class="n">next_tue</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="nf">now</span><span class="p">()</span>
                    <span class="o">+</span><span class="n">datetime</span><span class="p">.</span><span class="nf">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">2</span><span class="p">)).</span><span class="nf">strftime</span><span class="p">(</span><span class="sh">"</span><span class="s">%Y-%m-%d</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">url</span> <span class="o">=</span> <span class="sh">"</span><span class="s">https://some-confluence-url.com/rest/api/content/</span><span class="sh">"</span>
    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span> <span class="sh">"</span><span class="s">content-type</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">application/json</span><span class="sh">"</span> <span class="p">}</span>
    <span class="n">payload</span> <span class="o">=</span> <span class="p">{</span> <span class="sh">"</span><span class="s">type</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">blogpost</span><span class="sh">"</span><span class="p">,</span>
                <span class="sh">"</span><span class="s">title</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">Meeting: </span><span class="sh">"</span><span class="o">+</span><span class="n">next_tue</span><span class="p">,</span>
                <span class="sh">"</span><span class="s">space</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
                    <span class="sh">"</span><span class="s">key</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">mySpaceNameGoesHere</span><span class="sh">"</span>
                <span class="p">},</span>
                <span class="sh">"</span><span class="s">body</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
                    <span class="sh">"</span><span class="s">storage</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
                        <span class="sh">"</span><span class="s">representation</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">storage</span><span class="sh">"</span><span class="p">,</span>
                        <span class="sh">"</span><span class="s">value</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">Meeting description goes here.</span><span class="sh">"</span>
                    <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>

    
    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> 
                             <span class="n">data</span><span class="o">=</span><span class="n">json</span><span class="p">.</span><span class="nf">dumps</span><span class="p">(</span><span class="n">payload</span><span class="p">),</span> 
                             <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> 
                             <span class="n">auth</span><span class="o">=</span><span class="p">(</span><span class="sh">"</span><span class="s">myUserName</span><span class="sh">"</span><span class="p">,</span> <span class="sh">"</span><span class="s">mySecretPassword</span><span class="sh">"</span><span class="p">))</span>
    
    <span class="k">print</span> <span class="n">json</span><span class="p">.</span><span class="nf">dumps</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="nf">json</span><span class="p">(),</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">response</span><span class="p">.</span><span class="nf">json</span><span class="p">()</span></code></pre></figure>

<p>Now, I needed <a href="http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html" target="_blank">to package</a> the code to make it ready to deploy:</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c"># 1. create folder</span>
<span class="nb">mkdir </span>blogposter
<span class="nb">cd </span>blogposter

<span class="c"># 2. create and copy the code above into poster.py</span>
<span class="nb">touch </span>poster.py

<span class="c"># 3. install requests package locally</span>
pip <span class="nb">install </span>requests <span class="nt">-t</span> <span class="nb">.</span>

<span class="c"># 4. zip contents of the folder and create a zip file in a parent directory</span>
zip <span class="nt">-r9</span> ../pyposter.zip <span class="k">*</span></code></pre></figure>

<p>And we are ready to deploy to AWS! Start with creating a new Lambda Function and selecting a blank function for this job.</p>

<p><img src="/assets/images/posts-images/2017-01-29-confluence-and-aws_screen1.png" alt="Start with selecting a blueprint" /></p>

<p>I didn&#8217;t choose any triggers for now and continued to the configuration page. When presented with function configuration you need to give it a name, description, runtime, and a .zip file with the code. At the end, you will need to define a handler (which will typically be <code class="language-plaintext highlighter-rouge">filename.function_name</code>), and a role.</p>

<p><img src="/assets/images/posts-images/2017-01-29-confluence-and-aws_screen2.png" alt="Fill out the rest of info" /></p>

<p>At the end of the wizard, you can run it manually by pressing the Test button. If you did all the steps above, this should now create a new post on your Confluence. Congratulations, you have now set up a stand-alone function in the Cloud!</p>

<hr />

<h2 id="schedule-it">Schedule it!</h2>

<p>Now that I have automated the task and deployed it to the Cloud, I needed something to trigger that function. In this case, I wanted to schedule it to run weekly, so function was set to be triggered by the <a href="http://docs.aws.amazon.com/lambda/latest/dg/with-scheduled-events.html" target="_blank">CloudWatch</a> events. It offers a good support for <a href="http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/RunLambdaSchedule.html" target="_blank">scheduling Lambda expressions</a>.</p>

<p>I defined event source as a cron expression, and a target as a Lambda function I created in the previous step.</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c"># 9:05, every Sunday</span>
5 9 ? <span class="k">*</span> 1 <span class="k">*</span></code></pre></figure>

<p><img src="/assets/images/posts-images/2017-01-29-confluence-and-aws_screen3.png" alt="Adding a scheduled event" /></p>

<p>Now you (and I) have a function that is scheduled to run weekly and does not require a dedicated machine to run. It also has some good options for logging and sending alarms in case it fails.</p>

<hr />]]></content><author><name>Rustam Mehmandarov</name></author><summary type="html">Automating posting to Confluence with cloud services like Amazon Web Services (AWS).</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mehmandarov.com/assets/images/posts-images/clouds.jpg"/><category term="blog"/><category term="field notes"/><category term="automation"/><category term="cloud"/><category term="python"/><category term="english"/></entry></feed>
