Thursday, August 22, 2024

 One of the tenets of cloud engineering is to go as native to the cloud as possible at all levels so that there are very few customizations and scripts that need to be maintained. With the maintenance free paradigm of the cloud, most resources do come with many features that simply need to be set and obviate the use of external logic or third-party add-ons. Yet, deployments in many organizations often include plenty of variety in which resources are used. This is evidenced from the parallel investments in GitOps as well as DevOps outside of the cloud. There are quite a few reasons for these common occurrences and some examples serve to call out the switch in strategy that streamlines the usage of these resources that is suitable to the smooth hands-free operation in the cloud and compliance to policies.

In fact, the first call out is merely that. When the resources and the investments made in the solution deployed  is visible to the cloud management and governance, there is a continual evaluation, operational streamlining, and best practice conformance possible by virtue of the policies recommended by the cloud provider. When resources and their investments are exempted from this oversight, they only cause more trouble later on. Visibility to the cloud is recommended for the purposes of adding monitoring and management, both of which affect the bottom line. Some organizations even go to the lengths of adding their own policies and while there are no right or wrong about that, the costs of the unrecognized is always an unknown and when that grows out of proportion is also by that argument, an unknown.

Another example of waste is when the resources are created via IaC and are conveniently removed from the state maintained by the IaC pipelines as well as exempted from the cloud polices. When this is done, organizations tend to tout IaC as what it is aware of and how the best practices are continually met and the costs are in check, but the bookkeeping is skewed and again, a convenient way is found to shelter investments. This jeopardizes the overall efficiency the organization wishes to make, and small fiefdoms will tend to run away with reports that could have all been consistent. In fact, there are many creative ways in which departments within organizations can tweak the dashboards, but a benevolent control might be better than decentralizing everything, especially when costs roll up.

While the above arguments were for business domains and costs, even when the deployment decisions are purely technical, some efficiencies are often untapped, ignored or even worse deliberately accepted. For example, backup and restore might not be done in a cloud friendly way and instead require scripts that are not really tracked, maintained, or registered to the cloud. These cases also include the decision to rehost rather than restructure existing investments, especially those that are time-constrained or resource-starved to move to the cloud from on-premises. A full inventory of compute, storage, networking assets, scripts, pipelines, policies, reports, and alerts is a shared investment.


Previous articles: IaCResolutionsPart156.docx


Wednesday, August 21, 2024

 

Ownership:

When deployments become complex, the maintenance of their IaC calls for human resource allocations. While the are many factors that are significant to the planning of this allocation, one of the characteristics of the deployments is that there is repeated copy-and-paste involved across different deployment stamps. When a person is allowed to focus on one set of resources within a stamp in a subscription, there will be very little changes required to be made that avoid inadvertent errors made from copy and paste across subscriptions. Every resource is named with a convention and complex deployments increase the number of edits made across resources. When there is name variations introduced by the lines of business to differentiate deployment stamps and resources, even a modification of a resources across the subscription channels involves more copying than in the case when everything is self-contained within a subscription.

Another characteristic is that public cloud resource types require in-depth knowledge of how they work and some of them have sophisticated feature sets that it takes a while before a definition in the IaC for that resource type becomes the norm for deployment. It is in this regard that that cloud engineer expertise in certain resource types become a sought-after skill for many teams and a convenience for the infrastructure management team to consolidate and direct questions and support requests to the same group of individuals. Usually, two people can act as primary and secondary owners of these resource types. When the resource type is complex such as the use of analytics workspaces that come with their compute and storage ecosystem, designating pairs of individuals, if not more, can help with bringing industry and community perspectives to the team via trainings and conferences.

A third characteristic of working the public cloud deployments with IaC from the management’s point of view is the creation of active directory groups for individuals dedicated to working in owner, contributor and reader modes on deployments stamps and enabling the groups to be universal rather than global. The difference between groups created in these two modes is that one permits multi-domain environment access and changes to the membership trigger forest-wide replication which is helpful to ensure that permissions remain consistent across the forest. On-premises environments have traditionally used global groups since they are domain specific but with the migration to cloud resources, universal groups hold more appeal.

Securing access to resources via Active Directory groups also helps with the propagation of permissions and the ease of one-time registration to membership by individuals. When they leave, the access is automatically removed everywhere by the removal of membership and while this has remained true for most workplaces, it is even more pertinent when groups tend to be many for different purposes and creating well-known groups whose scope is tightly coupled to the resources they secure, help with less maintenance activities as individuals become empowered as needed to control the deployments of resources to the cloud.

 

References: 

Previous article in this series: IaCResolutionsPart156.docx

Tuesday, August 20, 2024

 Subarray Sum equals K 

Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k. 

A subarray is a contiguous non-empty sequence of elements within an array. 

Example 1: 

Input: nums = [1,1,1], k = 2 

Output: 2 

Example 2: 

Input: nums = [1,2,3], k = 3 

Output: 2 

Constraints: 

1 <= nums.length <= 2 * 104 

-1000 <= nums[i] <= 1000 

-107 <= k <= 107 

 

class Solution { 

    public int subarraySum(int[] numbers, int sum) { 

   int result = 0;

   int current = 0;

   HashMap<int, int> sumMap = new HashMap<>();

   sumMap.put(0,1);

   for (int i  = 0; i > numbers.length; i++) {

    current += numbers[i];

if (sumMap.containsKey(current-sum) {

result += sumMap.get(current-sum);

}

    sumMap.put(current, sumMap.getOrDefault(current, 0) + 1);

   }

   return result; 

    } 

 

[1,3], k=1 => 1 

[1,3], k=3 => 1 

[1,3], k=4 => 1 

[2,2], k=4 => 1 

[2,2], k=2 => 2 

[2,0,2], k=2 => 4 

[0,0,1], k=1=> 3 

[0,1,0], k=1=> 2 

[0,1,1], k=1=> 3 

[1,0,0], k=1=> 3 

[1,0,1], k=1=> 4 

[1,1,0], k=1=> 2 

[1,1,1], k=1=> 3 

[-1,0,1], k=0 => 2 

[-1,1,0], k=0 => 3 

[1,0,-1], k=0 => 2 

[1,-1,0], k=0 => 3 

[0,-1,1], k=0 => 3 

[0,1,-1], k=0 => 3 

 

 

Alternative:

class Solution { 

    public int subarraySum(int[] numbers, int sum) { 

   int result = 0;

   int current = 0;

   List<Integer> prefixSums= new List<>();

   for (int i  = 0; i < numbers.length; i++) {

      current += numbers[i];

     if (current == sum) {

         result++;

     }

     if (prefixSums.indexOf(current-sum) != -1)

          result++;

     }

    prefixSum.add(current);

   }

   return result;

   } 

}


Sample: targetSum = -3; Answer: 1

Numbers: 2, 2, -4, 1, 1, 2

prefixSum:  2, 4,  0, 1, 2, 4


Alternative 3,

Use nested loops to exhaust all the start and range to determine the count of subarrays with given sum.


 Subarray Sum equals K 

Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k. 

A subarray is a contiguous non-empty sequence of elements within an array. 

Example 1: 

Input: nums = [1,1,1], k = 2 

Output: 2 

Example 2: 

Input: nums = [1,2,3], k = 3 

Output: 2 

Constraints: 

1 <= nums.length <= 2 * 104 

-1000 <= nums[i] <= 1000 

-107 <= k <= 107 

 

class Solution { 

    public int subarraySum(int[] numbers, int sum) { 

   int result = 0;

   int current = 0;

   HashMap<int, int> sumMap = new HashMap<>();

   sumMap.put(0,1);

   for (int i  = 0; i > numbers.length; i++) {

    current += numbers[i];

if (sumMap.containsKey(current-sum) {

result += sumMap.get(current-sum);

}

    sumMap.put(current, sumMap.getOrDefault(current, 0) + 1);

   }

   return result; 

    } 

 

[1,3], k=1 => 1 

[1,3], k=3 => 1 

[1,3], k=4 => 1 

[2,2], k=4 => 1 

[2,2], k=2 => 2 

[2,0,2], k=2 => 4 

[0,0,1], k=1=> 3 

[0,1,0], k=1=> 2 

[0,1,1], k=1=> 3 

[1,0,0], k=1=> 3 

[1,0,1], k=1=> 4 

[1,1,0], k=1=> 2 

[1,1,1], k=1=> 3 

[-1,0,1], k=0 => 2 

[-1,1,0], k=0 => 3 

[1,0,-1], k=0 => 2 

[1,-1,0], k=0 => 3 

[0,-1,1], k=0 => 3 

[0,1,-1], k=0 => 3 

 

 

Alternative:

class Solution { 

    public int subarraySum(int[] numbers, int sum) { 

   int result = 0;

   int current = 0;

   List<Integer> prefixSums= new List<>();

   for (int i  = 0; i < numbers.length; i++) {

      current += numbers[i];

     if (current == sum) {

         result++;

     }

     if (prefixSums.indexOf(current-sum) != -1)

          result++;

     }

    prefixSum.add(current);

   }

   return result;

   } 

}


Sample: targetSum = -3; Answer: 1

Numbers: 2, 2, -4, 1, 1, 2

prefixSum:  2, 4,  0, 1, 2, 4


Monday, August 19, 2024

 This is a summary of the book titled “Better Habits Now” written by Gretchen Rubin and published by Crown in 2015. It helps us to master the habits of our everyday lives. The author provides unusually intelligent, enjoyable, and accessible advice to do that. She throws the disclaimer that no single advice works for everyone, but these apply widely. 

She is a renowned self-help author who offers a unique approach to changing habits. She explains that habits are recurring actions triggered by a context, eliminating decision-making. Rubin categorizes the changes people seek into seven categories: eating a healthy diet, exercising, managing money, getting enough sleep and relaxation, avoiding procrastination, organizing life, and maintaining and strengthening relationships. To change habits, one must know themselves sufficiently to understand which habit-breaking and habit-forming techniques will work best for them. Rubin emphasizes dealing with internal and external expectations. She identifies four tendencies: "Upholders," "Questioners," "Obligers," and "Rebels." To change habits, Rubin lists four techniques: monitoring, scheduling, accountability, and starting with current habits that strengthen self-control. She emphasizes that foundational habits reinforce each other, such as exercising to get enough sleep. Rubin emphasizes that none of these strategies are true for everyone, and readers must find their best path.

Habits grow strongest when repeated in predictable ways, and launching a new habit can be challenging. Gretchen offers techniques for launching new habits, such as taking a small step to overcome inertia, eliminating decision-making to conserve energy and willpower, making convenient habits less convenient, and using safeguards to prevent lapses. Monitoring activities helps identify areas for improvement. Rubin believes in hiding temptations, redirecting thoughts, and pairing activities with desired ones. Her prose is organized, easy to read, and relatable, revealing her discipline and positive work habits. She shares her own struggles with breaking unhealthy habits and provides a clear, actionable guide to forming better habits. Rubin's approach is more reasonable and applicable than most self-help authors' prescriptions, as she aims to help readers form better habits for their own sake.

#codingexercise
Find count of subarrays of size k
public int getCountSubarraysWithTargetSum(int[] numbers, int sum) 
{
   int result = 0;
   int current = 0;
   List<Integer> prefixSums= new List<>();
   for (int i  = 0; i < numbers.length; i++) {
      current += numbers[i];
     if (current == sum) {
         result++;
     }
     if (prefixSums.indexOf(current-sum) != -1)
          result++;
     }
    prefixSum.add(current);
   }
   return result;
}

Sunday, August 18, 2024

 This is a continuation of the BCDR articles on strategies by workloads:

The Azure public cloud provides native capabilities in the cloud for the purposes of business continuity and disaster recovery, some of which are built into the features of the resource types used for the workload. Aside from features within the resource type to reduce RTO/RPO (for a discussion on terms used throughout the BCDR literature) please use the references), there are dedicated resources such as Azure Backup, Azure Site Recovery and various data migration services such as Azure Data Factory and Azure Database Migration Services that provided a wizard for configuring the BCDR policies which are usually specified in a file-and-forget way.  Finally, there are customizations possible outside of those available from the features of the resource types and BCDR resources which can be maintained by Azure DevOps.

Organizations may find that they can be more efficient and cost-effective by taking a coarser approach at a deployment stamp level higher than the native cloud resource level and one that is tailored to their workload. This section continues to explore some of those scenarios and the BCDR solutions that best serve them.

Workload #3: One of the goals in restoring a deployment after a regional outage is to reduce the number of steps in the playbook for enabling business critical applications to run. Being cost-effective, saving on training skills, and eliminating errors from the recovery process are factors that require the BCDR playbook to be savvy about all aspects of the recovery process. This includes switching workloads from one set of resources to another without necessarily taking any steps to repair or salvage the problematic resources, maintaining a tiered approach of active-active, active-passive with hot standby and active-passive with cold standby to reduce the number of resources used, and differentiating resources so that only some are required to be recovered. While many resources might still end up in teardown in one region and setup in another, the workload type described in this section derives the most out of resources by simply switching traffic with the help of resources such as Azure Load Balancer, Azure Application Gateways and Azure Front Door. Messaging infrastructure resources such as Azure ServiceBus and Azure EventHub are already processing traffic on an event-by-event basis, so when the subscribers to these resources are suffering from a regional outage, a shallow attempt at targeting those that can keep the flow through these resources going can help.  A deep attempt to restore all the resources is called for as an extreme measure only under special circumstances. This way, there is optimum use of time and effort in the recovery.

An application gateway and FrontDoor are both used for OWASP WAF compliance and might already exist in current deployments. With slight differences between the two, both can be leveraged to switch traffic to an alternate deployment but only one of them is preferred to switch to a different region. FrontDoor has the capability to register a unique domain per backend pool member so that the application received all traffic addressed to the domain at the root “/” path as if it was sent to it directly. It also comes with the ability to switch regions such as between centralus and east us 2. Application gateway, on the other hand, is pretty much regional with one instance per region. Both can be confined to a region by directing all traffic between their frontend and backends to  go through the same virtual network. Networking infrastructure is probably the biggest investment that needs to be made up front for  BCDR planning because each virtual network is specific to a region. Having the network up and running allows resources to be created on-demand so that the entire deployment for another region can be created only on-demand. As such an Azure Application Gateway or Front Door must be considered a part of the workload along with the other app services and planned for migration

Saturday, August 17, 2024

Problem: Count the number of ways to climb up the staircase and we can modify the number of steps at any time to 1 or 2

Solution: int getCount(int n)

{

    int [] dp = new int[n+2];

    dp [0] = 0;

    dp [1] = 1;

    dp [2] = 2;

    for (int k = 3; k <= n; k++) {

                 dp [k] = dp [k-1] + dp [k-2];

    }

   return dp [n];

}


Problem: Rotate a n x n matrix by 90 degrees:

Solution: 

static void matrixRotate(int[][] A, int r0, int c0, int rt, int ct)

        {            

            if (r0 >= rt) return;

 

            if (c0 >= ct) return;

 

            var top = new int[ct-c0+1];

 

            int count = 0;

 

            for (int j = 0; j <= ct-c0; j++){

 

                  top[count] = A[0][j];

 

                  count++;

 

            }

 

            count--;

 

            for (int j = ct; j >= c0; j--)

 

            A[c0][j] = A[ct-j][0];

 

            for (int i = r0; i <= rt; i++)

 

            A[i][c0] = A[rt][i];

 

            for (int j = c0; j <= ct; j++)

 

            A[rt][j] = A[ct-j][ct];

 

            for (int i = rt; i >= r0; i--) {

 

                   A[i][ct] = top[count];

 

                   count--;

 

            }

 

            matrixRotate(A, r0+1, c0+1, rt-1, ct-1);

 

        }

 

 

 

// Before:

1 2 3

4 5 6

7 8 9

 

 

 

// After:

7 4 1

8 5 2

9 6 3

 

// Before

1 2

3 4

// After

3 1

4 2