Managing Multiple AWS Environments with Ease: Sceptre and AWS CDK in Harmony

You probably know about AWS CDK: “The AWS Cloud Development Kit (AWS CDK) lets you define your cloud infrastructure as code in one of its supported programming languages.“; Sceptre (open source tool by Cloudreach) adds an extra layer of power for DevOps engineers: “Sceptre is a tool to drive CloudFormation. Sceptre manages the creation, update and deletion of stacks while providing meta commands which allow users to retrieve information about their stacks.

As you see, they both have something important in common: CloudFormation. the output of an AWS CDK program is an AWS CloudFormation template and Sceptre leverages CloudFormation templates to streamline stack deployments. Think of Sceptre as the conductor that orchestrates your CDK-defined infrastructure across multiple environments. It lets you focus on writing concise CDK code while Sceptre handles the environment-specific configurations and deployments. I found this article in Dev community website a good and brief explanation about Sceptre. The good news is that Sceptre supports AWS CDK as templating source. The following diagram makes it clear how this works:

Managing diverse environments such as Development, Test, Acceptance, Staging and numerous production clusters with unique configurations can be a nightmare. Sceptre saved my day by simplifying deployments across them all using the same infrastructure code (plain CloudFormation templates, Troposphere or CDK)! Also, separating configuration plane from code plane and ability to pass parameters across the stacks makes it very useful for DevOps teams. I used troposphere for templating but its development lost its momentum and couldn’t keep up with official CloudFormation updates. So, when I heard about AWS CDK support in Sceptre, it was like dream comes true!

I gave it a try and I’m very happy with it. I didn’t have to change anything in the existing code but instead leveraged AWS CDK for new stacks. Amazingly, cross-stack references, hooks, parameter handling features all worked as before. This is possible because of modular design of sceptre and its reusability capabilities.

Now, Let’s have a look at an example. The following python code creates a simple OpenSearch cluster using its CDK construct:

from aws_cdk import CfnOutput, CfnParameter
from aws_cdk import aws_certificatemanager as acm
from aws_cdk import aws_route53 as r53
from aws_cdk import aws_iam as iam
from sceptre_cdk_handler import SceptreCdkStack
from aws_cdk import aws_opensearchservice as opensearch
from aws_cdk import aws_ec2 as ec2


# Important: Notice how it subclasses SceptreCdkStack and passes **kwargs into the base class's
# __init__(). This is important to maintain compability with the different deployment_types.
class OpenSearchStack(SceptreCdkStack):
def __init__(self, scope, id: str, sceptre_user_data: dict, **kwargs):
super().__init__(scope, id, sceptre_user_data, **kwargs)
# If you want to pass parameters like you do elsewhere in Sceptre, this works great!
self.num_data_nodes = CfnParameter(self, 'NumOfDataNodes', type='Number')
self.data_node_type = CfnParameter(self, 'DataNodeType')
self.data_node_size = CfnParameter(self, 'DataNodeSize', type='Number')
self.os_username = CfnParameter(self, 'Username', default='flybits-admin')
self.warm_node_type = CfnParameter(self, 'WarmNodeType', default='ultrawarm1.medium.search')
self.master_node_type = CfnParameter(self, 'MasterNodeType', default='r5.large.search')

self.num_az = int(sceptre_user_data['NumOfAZs'])
self.version = sceptre_user_data['Version']
self.num_of_warm_nodes = sceptre_user_data['NumOfWarmNodes']
self.num_of_master_nodes = sceptre_user_data['NumOfMasterNodes']

if self.num_of_warm_nodes == 'None':
self.num_of_warm_nodes = None
if self.num_of_master_nodes == 'None':
self.num_of_master_nodes = None


slr = iam.CfnServiceLinkedRole(
self, "Service Linked Role",
aws_service_name="es.amazonaws.com"
)

self.os_domain=opensearch.Domain(self, "OS_Domain",
version=opensearch.EngineVersion.open_search(version=self.version),
enable_version_upgrade=True,
capacity=opensearch.CapacityConfig(
data_node_instance_type=self.data_node_type.value_as_string,
data_nodes=self.num_data_nodes.value_as_number,
warm_nodes=self.num_of_warm_nodes,
warm_instance_type=self.warm_node_type.value_as_string,
master_nodes=self.num_of_master_nodes,
master_node_instance_type=self.master_node_type.value_as_string,
),
zone_awareness=opensearch.ZoneAwarenessConfig(
availability_zone_count=self.num_az
),
ebs=opensearch.EbsOptions(
volume_type=ec2.EbsDeviceVolumeType.GP3,
volume_size=self.data_node_size.value_as_number
),
encryption_at_rest=opensearch.EncryptionAtRestOptions(
enabled=True
),
node_to_node_encryption=True,
enforce_https=True,

fine_grained_access_control=opensearch.AdvancedSecurityOptions(
master_user_name=self.os_username.value_as_string,
)
)

self.resource_arn = self.os_domain.domain_arn + "/*"
self.os_domain.add_access_policies(iam.PolicyStatement(
actions=["es:*"],
effect=iam.Effect.ALLOW,
principals=[iam.AnyPrincipal()],
resources=[self.resource_arn]
))

its sceptre configuration looks like the following:

template:
type: cdk
# The path is always within your project's templates/ directory.
path: logging/opensearch.py
deployment_type: bootstrapless
bootstrapless_config:
file_asset_bucket_name: !stack_attr template_bucket_name
# It can be useful to apply the same prefix as your template_key_prefix to ensure your
# assets are namespaced similarly to the rest of Sceptre's uploaded artifacts.
file_asset_prefix: "cdk-assets"
class_name: OpenSearchStack

# Parameters are DEPLOY-TIME values passed to the CloudFormation template. Your CDK stack construct
# needs to have CfnParameters in order to support this, though.
parameters:
NumOfDataNodes: "2"
DataNodeType: "r6g.large.search"
DataNodeSize: "100"

sceptre_user_data:
NumOfAZs: "2"
RoleNeeded: true
Version: "2.7"
NumOfWarmNodes: None
NumOfMasterNodes: None

In specific look at the flexibility of introducing values for parameters in code. In sceptre we have 2 ways of passing values: first is parameters which is equivalent to setting values for CloudFormation parameters and the other is sceptre_user_data which is specific to sceptre and its resolvers take care of assigning the values in code. I brought both in code to show their use case. In specific, for variables like NumOfWarmNodes which their value can be a number or None , you can’t use parameters because it doesn’t accept 2 different types; instead sceptre_user_data is very helpful and you can easily assign None or a Number (please see the code)

As conclusion, if you are already using CloudFormation or AWS CDK and you are looking for a flexible and structured way of managing multiple environments using the same infrastructure as code, a combination of Sceptre and AWS CDK is highly recommended.

Is Microservices Architecture Cheap or expensive?

In the ever-evolving landscape of software architecture, the debate surrounding microservices and monolithic architecture has raged on for years. Back in 2015, I remember discussing with a software architect about Kubernetes. He was understandably very interested in migrating applications to a microservices based architecture and adopting Kubernetes. One of his most important selling points was the costs. However, as time has shown, the reality of microservices architecture isn’t always as cost-effective as it might seem at first glance.

Microservices architecture has been touted for its ability to enhance flexibility and increase productivity and efficiency. Yet, the hidden costs associated with this approach have become apparent over time. Let’s dissect some of the key financial aspects.

Data Transfer Costs: In a microservices environment, communication between different services is frequent and essential. However, this constant communication leads to data transfer costs, which can significantly impact your budget. While techniques like Topology Aware Hints (TAH) can help mitigate these costs to some extent, they remain a noteworthy expenditure.

Operational Overhead: Microservices require the use of sidecars, service meshes, and a host of tools for operational and management purposes. These components are often more complex and resource-intensive than their counterparts used in monolithic applications, contributing to increased operational costs.

So, Does it mean microservices architecture is more expensive? or as David Heinemeier Hansson (Creator of Ruby on Rails) says microservices don’t make sense?

Well, in my opinion it depends (I know the cliche!). If we compare microservices architecture to a well-designed monolithic architecture, its direct costs are in general higher; However, the benefits of microservices, such as flexibility and increased productivity, often lead to lower indirect costs associated with management and operations.

Consider the Example of AWS Prime Video: By transitioning away from microservices to a monolithic architecture, AWS reportedly achieved a 90% cost reduction. This demonstrates that simplicity can be a compelling factor in favor of monolithic architecture in certain scenarios.

Nevertheless, it’s important to note that many applications thrive in Kubernetes or other orchestrators, with stakeholders satisfied with their choice. The CNCF (Cloud Native Computing Foundation) community acknowledges the cost challenges and actively works on mitigating them through initiatives like TAH (Topology Aware Hints) and Karpenter.

In conclusion, the debate over whether microservices architecture is more expensive than monolithic architecture isn’t easily settled. Both approaches have their merits and drawbacks, and the cost-effectiveness of each depends on the specific use case and how well they are implemented.

As technology evolves, we can expect ongoing discussions about the financial aspects of software architecture. With initiatives like TAH and Karpenter, the CNCF community is actively addressing the cost challenges associated with microservices. Therefore, the future promises further exploration and innovation in the quest for cost-effective software solutions. Stay tuned for more developments in the years to come.

AWS Managed Prometheus and Grafana

AWS re:Invent 2020 is in progress and it’s full of introducing new services. For people like me who work day by day on both public cloud services (AWS in specific) and cloud native ecosystem, introductions of 2 services related to Observability were very interesting:

They are in Preview but AWS provides it to all users already. Of course they may be subject to changes and not recommended for production.

I really like such services because there is no vendor locking concern and like other managed services can be used at scale. Other advantages are integration with other services including IAM. Although there are solutions for scalability or securing these services but they are not easy to implement and the cost of maintaining them can be high.

I’m really excited to see how they work in practice but I wanted to share my view with you, maybe you are quicker than me in employing them and playing around 🙂

Healthcheck with Serverspec

As I mentioned in my previous post, I would like to introduce a project I have recently started which is a Chef cookbook about system healthcheck.

The idea is to generate a healthcheck page based on results of running Serverspec tests.  Specifically, it would be helpful for load balancers and more specifically for AWS ELB healthcheck. According to Serverspec: it tests your servers’ actual state by executing command locally, via SSH, via WinRM, via Docker API and so on. So you don’t need to install any agent softwares on your servers and can use any configuration management tools. But the true aim of Serverspec is to help refactoring infrastructure code. Load Balancers check health of system using this healthcheck URL and stop sending traffic if it’s not healthy. The generated health check page can be handy for this URL then. If self-check fails, it will return an error status code, otherwise 200 status code. In this cookbook, 2 concepts are used:

  • Infrastructure test as code using Serverspec: It’s best if we have a test-driven infrastructure as code but even if there is no code for infrastructure, this cookbook can still help!
  • Loadbalancer healthcheck: if healthchek page is comprehensive enough, this check can help in having a high available system. In case of AWS, when ELB is accompanied by Auto Scaling Group, a new healthy instance will replace the bad one if ELB notices an issue.

So, if you are interested in test driven coding especially in infrastructure, please have a look. Looking forward to hear your feedbacks.

Top vBlog voting

Time goes fast! It was not a long time ago when I was listed in Virtualization and Cloud portal (vLaunchpad) and it’s my pleasure that I’m a candidate now. So, if you like this blog, please go and cast your vote here. Please remember that you should choose 10 items to proceed.You can also find winners for last year in vLaunchpad main page.

VMWARE VSPHERE BIG DATA EXTENSIONS INSTALLATION – 2

To install VMware vSphere Big Data Extensions 1.1, if you satisfy the requirements mentioned in vmware document, go ahead with installation by deploying Big Data Extensions OVA as documented. But attention that:

  • Better to create a specific Resource Pool for your Big Data Cluster and specify the total amount of resources you want to assign and apply possible limits.
  • Create a port group dedicated to Big Data Extensions  as a communication link between management servers and working VMs.
  • When deploying Big Data Extensions Management server (OVA), ‘setup networks’ asks you to assign a destination port group. Note that: Management Network will use this network to communicate with vCenter server. So, if you use VLAN tags, the port group should be in the same VLAN (use same VLAN id) with vCenter network. If vCenter can not see Big Data Management server and vice versa, integration will not be made properly.

bigD_plugin4

  • In ‘Customize template’ step, there are 2 important settings: SSO service and Management Server IP address. So, from right-pane open ‘VC SSO Lookup Service URL’ and ‘Management Server Networks Settings’. Enter appropriate values. For SSO Lookup Service URL, use vCenter server with the same format (if you didn’t change defaults), I mean port 7444/lookupservice/sdk. Use FQDN of vCenter and not IP address or certificate will not be accepted and you will see errors for connecting Big Data Extensions plugin to Serengeti server in the future.

bigdata_sso1

Supported Hardware Version in Provider vDC

Remember to change default value of “Highest supported hardware version” from 7 to 9 when you create a Provider vDC in VMware vCloud Director 5 or you will face some issues later on when you want to import VM’s from vCenter to your Catalogs and will get this error message:
“The selected vdc does not support required virtual hardware version”
The interesting point is that VM’s in vCenter are created compatible to Hardware Version 8 by default! In fact, there are some inconsistencies between vCenter, vSphere and vCloud Director; it is just one of them.

To get started …

Well, there should be a beginning for everything and yes, it’s the beginning for this blog! So, let’s go over this cliche quick.

It’s going to be a technical blog about networking, as its name implies: some tweets about networking! I’m prone to cloud topics, though it won’t be limited to cloud stuff. You may ask do we need just another blog about networking or cloud computing? Ummm, I would say the number of ways to approach a problem equals the number of people who think about it. Networking and cloud is not a different story and this variety in techniques is beautiful!

My name is Mehdi Kianpour, now living in Canada. It’s like 15 years I’m working in this field and I think I can add something to online resources that may help other people fix their issues or understand a concept quicker. Recently, I’m engaged in some projects that are dependant on cloud technologies. Of course, we all know that cloud is the new (almost new) trend, while comparing to other networking stuff, there is less independent information over Internet. I will try to talk about some less experienced tasks and address some yet unknown issues and I hope this blog to be useful in this field.

And last but not least, I’m looking forward to hear from everybody (in specific other specialists) in my blog about the topics I cover or any other comment. So, see you soon!