Integrating ML models into production pipelines with Dataflow

Google Cloud’s Dataflow recently announced the General Availability support for Apache Beam’s generic machine learning prediction and inference transform, RunInference. In this blog, we will take a deeper dive on the transform, including:Showing the RunInference transform used with a simple model as an example, in both batch and streaming mode.Using the transform with multiple models in an ensemble.Providing an end-to-end pipeline example that makes use of an open source model from Torchvision. In the past, Apache Beam developers who wanted to make use of a machine learning model locally, in a production pipeline, had to hand-code the call to the model within a user defined function (DoFn), taking on the technical debt for layers of boilerplate code. Let’s have a look at what would have been needed:Load the model from a common location using the framework’s load method.Ensure that the model is shared amongst the DoFns, either by hand or via the shared class utility in Beam.Batch the data before the model is invoked to improve the model efficiency. The developer would set this up, either by hand or via one of the groups into batches utilities.Provide a set of metrics from the transform.Provide production grade logging and exception handling with clean messages to help that SRE out at 2 in the morning! Pass specific parameters to the models, or start to build a generic transform that allows the configuration to determine information within the model. And of course these days, companies need to deploy many models, so the data engineer begins to do what all good data engineers do and builds out an abstraction for the models. Basically, each company is building out their own RunInference transform!  Recognizing that all of this activity is mostly boilerplate regardless of the model, the RunInference API was created. The inspiration for this API comes from the tfx_bsl.RunInference transform that the good folks over at TensorFlow Extended built to help with exactly the issues described above. tfx_bsl.RunInference was built around TensorFlow models. The new Apache Beam RunInference transform is designed to be framework agnostic and easily composable in the Beam pipeline. The signature for RunInference takes the form of RunInference(model_handler), where the framework-specific configuration and implementation is dealt with in the model_handler configuration object. This creates a clean developer experience and allows for new frameworks to be easily supported within the production machine learning pipeline, without disrupting the developer workflow.. For example, NVIDIA is contributing to the Apache Beam project to integrateNVIDIA TensorRTTM, an SDK that can optimize trained models for deployment with the highest throughput and lowest latency on NVIDIA GPUs within Google Dataflow (PullRequest).  Beam Inference also allows developers to make full use of the versatility of Apache Beam’s pipeline model, making it easier to build complex multi-model pipelines with minimum effort. Multi-model pipelines are useful for activities like A/B testing and building out ensembles. For example, doing natural language processing (NLP) analysis of text and then using the results within a domain specific model to drive a customer recommendation. In the next section, we start to explore the API using code from the public codelab with the notebook also available at github.com/apache/beam/examples/notebooks/beam-ml.Using the Beam Inference APIBefore we get into the API, for those who are unfamiliar with Apache Beam, let’s put together a small pipeline that reads data from some CSV files to get us warmed up on the syntax.code_block[StructValue([(u’code’, u”import apache_beam as beamrnrnwith beam.Pipeline() as p:rn data = p | beam.io.ReadFromText(‘./file.csv’) rn data | beam.Map(print)”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa26ab6d0>)])]In that pipeline, we used the ReadFromText source to consume the data from the CSV file into a Parallel Collection, referred to as a PCollection in Apache Beam. In Apache Beam syntax, the pipe ‘|’ operator essentially means “apply”, so the first line applies the ReadFromText transform. In the next line, we use a beam.Map() to do element-wise processing of the data; in this case, the data is just being sent to the print function.Next, we make use of a very simple model to show how we can configure RunInference with different frameworks. The model is a single-layer linear regression that has been trained on y = 5x data (yup, it’s learned its fives times table). To build this model, follow the steps in the codelab. The RunInference transform has the following signature: RunInference(ModelHandler). The ModelHandler is a configuration that informs RunInference about the model details and that provides type information for the output. In the codelab, the PyTorch saved model file is named ‘five_times_table_torch.pt’ and is output as a result of the call to torch.save() on the model’s state_dict. Let’s create a ModelHandler that we can pass to RunInference for this model:code_block[StructValue([(u’code’, u”my_handler = PytorchModelHandlerTensor(rn state_dict_path=./five_times_table_torch.pt,rn model_class=LinearRegression,rn model_params={‘input_dim': 1,rn ‘output_dim': 1}”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa926196d0>)])]The model_class is the class of the PyTorch model that defines the model architecture as a subclass of torch.nn.Module. The model_params are the ones that are defined by the constructor of the model_class. In this example, they are used in the notebook LinearRegression class definition:code_block[StructValue([(u’code’, u’class LinearRegression(torch.nn.Module):rn def __init__(self, input_dim=1, output_dim=1):rn super().__init__()rn self.linear = torch.nn.Linear(input_dim, output_dim) rn def forward(self, x):rn out = self.linear(x)rn return out’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa25e92d0>)])]The ModelHandler that is used also provides the transform information about the input type to the model, with PytorchModelHandlerTensor expecting torch.Tensor elements.To make use of this configuration, we update our pipeline with the configuration. We will also do the pre-processing needed to get the data into the right shape and type for the model that has been created. The model expects a torch.Tensor of shape [-1,1] and the data in our CSV file is in the format 20,30,40.code_block[StructValue([(u’code’, u”with beam.Pipeline() as p:rn raw_data = p | beam.io.ReadFromText(‘./file.csv’)rn shaped_data = raw_data | beam.FlatMap(lambda x : rn [numpy.float32(y).reshape(-1,1) rn for y in x.split(‘,’)]))rn results = shaped_data | beam.Map(torch.Tensor) | RunInference(my_handler)rn results | beam.Map(print)”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa91962f50>)])]This pipeline will read the CSV file, get the data into shape for the model, and run the inference for us. The result of the print statement can be seen here:PredictionResult(example=tensor([20.]), inference=tensor([100.0047], grad_fn=<UnbindBackward0>))The PredictionResult object contains both the example as well as the result, in this case 100.0047 given an input of 20. Next, we look at how composing multiple RunInference transforms within a single pipeline gives us the ability to build out complex ensembles with a few lines of code. After that, we will look at a real model example with TorchVision.Multi model pipelinesIn the previous example, we had one model, a source, and an output. That pattern will be used by many pipelines. However, business needs also require ensembles of models where models are used for pre-processing of the data and for the domain specific tasks. For example, conversion of speech to text before being passed to an NLP model. Though the diagram above is a complex flow, there are actually three primary patterns. 1- Data is flowing down the graph.2- Data can branch after a stage, for example after ‘Language Understanding’.3- Data can flow from one model into another.Item 1 means that this is a good fit for building into a single Beam pipeline because it’s acyclic. For items 2 and 3, the Beam SDK can express the code very simply. Let’s take a look at these.Branching Pattern:In this pattern, data is branched to two models. To send all the data to both models, the code is in the form:code_block[StructValue([(u’code’, u’model_a_predictions = shaped_data | RunInference(configuration_model_a)rn model_b_predictions = shaped_data | RunInference(configuration_model_b)’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa2307890>)])]Models in Sequence:In this pattern, the output of the first model is sent to the next model. Some form of post processing normally occurs between these stages. To get the data in the right shape for the next step, the code is in the form:code_block[StructValue([(u’code’, u’model_a_predictions = shaped_data | RunInference(configuration_model_a)rnmodel_b_predictions = (model_a_predictions | beam.Map(postprocess) rn | RunInference(configuration_model_b))’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa031ff50>)])]With those two simple patterns (branching and model in sequence) as building blocks, we see that it’s possible to build complex ensembles of models. You can also make use of other Apache Beam tools to enrich the data at various stages in these pipelines. For example, in a sequential model, you may want to join the output of model a with data from a database before passing it to model b, bread and butter work for Beam. Using an open source modelIn the first example, we used a toy model that was available in the codelab. In this section, we walk through how you could use an open source model and output the model data to a Data Warehouse (Google Cloud BigQuery) to show a more complete end-to-end pipeline.Note that the code in this section is self-contained and not part of the codelab used in the previous section. The PyTorch model we will use to demonstrate this is maskrcnn_resnet50_fpn, which comes with Torchvision v 0.12.0. This model attempts to solve the image segmentation task: given an image, it detects and delineates each distinct object appearing in that image with a bounding box.In general, libraries like Torchvision pretrained models download the pretrained model directly into memory. To run the model with RunInference, we need a different setup, because RunInference will load the model once per Python process to be shared amongst many threads. So if we want to use a pre-trained model from these types of libraries, we have a little bit of setup to do. For this PyTorch model we need to:1- Download the state dictionary and make it available independently of the library to Beam.2- Determine the model class file and provide it to our ModelHandler, ensuring that we disable the class’s ‘autoload’ features.When looking at the signature for this model with version 0.12.0, note that there are two parameters that initiate an auto-download: pretrained and pretrained_backbone. Ensure these are both set to False to make sure that the model class does not load the model files:model_params = {‘pretrained': False, ‘pretrained_backbone': False}Step 1 – Download the state dictionary. The location can be found in the maskrcnn_resnet50_fpn source code:code_block[StructValue([(u’code’, u’%pip install apache-beam[gcp] torch==1.11.0 torchvision==0.12.0′), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa2873c10>)])]code_block[StructValue([(u’code’, u’import os,iornfrom PIL import Imagernfrom typing import Tuple, Anyrnimport torch, torchvisionrnimport apache_beam as beamrnfrom apache_beam.io import fileiornfrom apache_beam.io.gcp.internal.clients import bigqueryrnfrom apache_beam.options.pipeline_options import PipelineOptionsrnfrom apache_beam.options.pipeline_options import SetupOptionsrnfrom apache_beam.ml.inference.base import KeyedModelHandlerrnfrom apache_beam.ml.inference.base import PredictionResultrnfrom apache_beam.ml.inference.pytorch_inference import PytorchModelHandlerTensor’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa2873d10>)])]code_block[StructValue([(u’code’, u”# Download the state_dict using the torch hub utility to a local models directoryrntorch.hub.load_state_dict_from_url(‘https://download.pytorch.org/models/maskrcnn_resnet50_fpn_coco-bf2d0c1e.pth’, ‘models/’)”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa9371a9d0>)])]Next, push this model from the local directory where it was downloaded to a common area accessible to workers. You can use utilities like gsutil if using Google Cloud Storage (GCS) as your object store:code_block[StructValue([(u’code’, u”model_path = f’gs://{bucket}/models/maskrcnn_resnet50_fpn_coco-bf2d0c1e.pth'”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa916f93d0>)])]Step 2 – For our Modelandler, we need to use the model_class, which in our case is torchvision.models.detection.maskrcnn_resnet50_fpn. We can now build our ModelHandler. Note that in this case, we are making a KeyedModelHandler, which is different from the simple example we used above. The KeyedModelHandler is used to indicate that the values coming into the RunInference API are a tuple, where the first value is a key and the second is the tensor that will be used by the model. This allows us to keep a reference of which image the inference is associated with, and it is used in our post processing step.code_block[StructValue([(u’code’, u”my_cloud_model_handler = PytorchModelHandlerTensor(rn state_dict_path=model_path,rn model_class=torchvision.models.detection.maskrcnn_resnet50_fpn,rn model_params={‘pretrained':False, ‘pretrained_backbone’ : False})rnrnmy_keyed_cloud_model_handler = KeyedModelHandler(my_cloud_model_handler)”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa916f9990>)])]All models need some level of pre-processing. Here we create a preprocessing function ready for our pipeline. One important note: when batching, the PyTorch ModelHandler will need the size of the tensor to be the same across the batch, so here we set the image_size as part of the pre-processing step. Also note that this function accepts a tuple with the first element being a string. This will be the ‘key’, and in the pipeline code, we will use the filename as the key.code_block[StructValue([(u’code’, u’# In this function we can carry out any pre-processing steps that you need for the modelrnrndef preprocess_image(data: Tuple[str,Image.Image]) -> Tuple[str,torch.Tensor]:rn import torchrn import torchvision.transforms as transformsrn # Note RunInference will by default auto batch inputs for Torch modelsrn # Alternative to this is to create a wrapper class, and overriding the batch_elements_kwargsrn # function to return {max_batch_size=1}set max_batch_size=1rn image_size = (224, 224)rn transform = transforms.Compose([rn transforms.Resize(image_size),rn transforms.ToTensor(),rn ])rn return data[0], transform(data[1])’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa916f9310>)])]The output of the model needs some post processing before being sent to BigQuery. Here we denormalise the label with the actual name, for example, person, and zip it up with the bounding box and score output:code_block[StructValue([(u’code’, u”# The inference result is a PredictionResult object, this has two components the example and the inferencerndef post_process(kv : Tuple[str, PredictionResult]):rn # We will need the coco labels to translate the output from the modelrn coco_names = [‘unlabeled’, ‘person’, ‘bicycle’, ‘car’, ‘motorcycle’,rn ‘airplane’, ‘bus’, ‘train’, ‘truck’, ‘boat’, ‘traffic light’,rn ‘fire hydrant’, ‘street sign’, ‘stop sign’, ‘parking meter’,rn ‘bench’, ‘bird’, ‘cat’, ‘dog’, ‘horse’, ‘sheep’, ‘cow’,rn ‘elephant’, ‘bear’, ‘zebra’, ‘giraffe’, ‘hat’, ‘backpack’,rn ‘umbrella’, ‘shoe’, ‘eye glasses’, ‘handbag’, ‘tie’, ‘suitcase’,rn ‘frisbee’, ‘skis’, ‘snowboard’, ‘sports ball’, ‘kite’,rn ‘baseball bat’, ‘baseball glove’, ‘skateboard’, ‘surfboard’,rn ‘tennis racket’, ‘bottle’, ‘plate’, ‘wine glass’, ‘cup’, ‘fork’,rn ‘knife’, ‘spoon’, ‘bowl’, ‘banana’, ‘apple’, ‘sandwich’,rn ‘orange’, ‘broccoli’, ‘carrot’, ‘hot dog’, ‘pizza’, ‘donut’,rn ‘cake’, ‘chair’, ‘couch’, ‘potted plant’, ‘bed’, ‘mirror’,rn ‘dining table’, ‘window’, ‘desk’, ‘toilet’, ‘door’, ‘tv’,rn ‘laptop’, ‘mouse’, ‘remote’, ‘keyboard’, ‘cell phone’,rn ‘microwave’, ‘oven’, ‘toaster’, ‘sink’, ‘refrigerator’,rn ‘blender’, ‘book’, ‘clock’, ‘vase’, ‘scissors’, ‘teddy bear’,rn ‘hair drier’, ‘toothbrush’]rn # Extract the outputrn output = kv[1].inferencern # The model outputs labels, boxes and scores, we pull these out and creatern # a tuple with the label mapped to the coco_names and convert the tensorsrn return {‘file’ : kv[0], ‘inference’ : [rn {‘label': coco_names[x],rn ‘box’ : y.detach().numpy().tolist(),rn ‘score’ : z.item()}rn for x,y,z in zip(output[‘labels’],rn output[‘boxes’],rn output[‘scores’])]}”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa424bb50>)])]Let’s now run this pipeline with the direct runner, which will read the image from GCS, run it through the model, and output the results to BigQuery. We will need to pass in the BigQuery schema that we want to use, which should match the dict that we created in our post-processing. The WriteToBigquery transform takes the schema information as the table_spec object, which represents the following schema:The schema has a file string, which is the key from our output tuple. Because each image’s prediction will have a List of (labels, score, and bounding box points), a RECORD type is used to represent the data in BigQuery.Next, let’s create the pipeline using pipeline options, which will use the local runner to process an image from the bucket and push it to BigQuery. Because we need access to a project for the BigQuery calls, we will pass in project information via the options:code_block[StructValue([(u’code’, u”pipeline_options = PipelineOptions().from_dictionary({rn ‘temp_location':f’gs://{bucket}/tmp’,rn ‘project': project})”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa2c25310>)])]Next, we will see the pipeline put together with pre- and post-processing steps. The Beam transform MatchFiles matches all of the files found with the glob pattern provided. These matches are sent to the ReadMatches transform, which outputs a PCollection of ReadableFile objects. These have the Metadata.path information and can have the read() function invoked to get the files bytes(). These are then sent to the preprocessing path.code_block[StructValue([(u’code’, u’pipeline_options = PipelineOptions().from_dictionary({rn ‘temp_location':f’gs://{bucket}/tmp’,rn ‘project': project})rnrn# This function is a workaround for a dependency issue caused by usage of PILrn# within a lambda from a notebookrndef open_image(readable_file):rn import iorn from PIL import Imagern return readable_file.metadata.path, Image.open(io.BytesIO(readable_file.read()))rnrnpipeline_options.view_as(SetupOptions).save_main_session = Truernrnwith beam.Pipeline(options=pipeline_options) as p:rn (prn | “ReadInputData” >> beam.io.fileio.MatchFiles(f’gs://{bucket}/images/*’)rn | “FileToBytes” >> beam.io.fileio.ReadMatches()rn | “ImageToTensor” >> beam.Map(open_image)rn | “PreProcess” >> beam.Map(preprocess_image)rn | “RunInferenceTorch” >> beam.ml.inference.RunInference(my_keyed_cloud_model_handler)rn | beam.Map(post_process)rn | beam.io.WriteToBigQuery(table_spec,rn schema=table_schema,rn write_disposition=beam.io.BigQueryDisposition.WRITE_TRUNCATE,rn create_disposition=beam.io.BigQueryDisposition.CREATE_IF_NEEDED)rn )’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa2c25850>)])]After running this pipeline, the BigQuery table will be populated with the results of the prediction.In order to run this pipeline on the cloud, for example if we had a bucket of 10000’s of images, we simply need to update the pipeline options and provide Dataflow with dependency information.:Create requirements.txt file for the dependencies:code_block[StructValue([(u’code’, u’!echo -e “apache-beam[gcp]ntorch==1.11.0ntorchvision==0.12.0″ > requirements.txt’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaa939fff10>)])]Creating the right pipeline options:code_block[StructValue([(u’code’, u”pipeline_options = PipelineOptions().from_dictionary({rn ‘runner’ : ‘DataflowRunner’,rn ‘region’ : ‘us-central1′,rn ‘requirements_file’ : ‘./requirements.txt’,rn ‘temp_location':f’gs://{bucket}/tmp’,rn ‘project': project})”), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eaaa098e1d0>)])]Conclusion The use of the new Apache Beam apache_beam.ml.RunInference transform removes large chunks of boiler plate data pipelines that incorporate machine learning models. Pipelines that make use of these transforms will also be able to make full use of the expressiveness of Apache Beam to deal with the pre- and post-processing of the data, and build complex multi-model pipelines with minimal code.
Quelle: Google Cloud Platform

Leading towards more trustworthy compliance through EU Codes of Conduct

Google is committed to be the best possible place for sustainable digital transformation for European organizations. Our Cloud on Europe’s terms initiative works to meet regional requirements for security, privacy, and digital sovereignty, without compromising on functionality or innovation. In support of this initiative, we are making our annual declaration of adherence to two important EU codes of conduct for cloud service providers: the SWIPO Code of Conduct and the EU Cloud Code of Conduct. We believe that codes of conduct are effective collaboration instruments among service providers and data protection authorities, where state-of-the-art industry practices can be tailored to meet robust European data protection requirements.The SWIPO Codes of ConductGoogle believes in an open cloud that gives organizations the ability to build, move, and use their applications across multiple environments. Portability and interoperability are key building blocks of that vision. SWIPO (Switching Cloud Providers and Porting Data) is a multi-stakeholder group facilitated by the European Commission, in order to develop voluntary Codes of Conduct for the proper application of Article 6 “Porting of Data” of the EU Free Flow of Non-Personal Data Regulation. To help demonstrate our commitment, Google adheres to the SWIPO Codes of Conduct for Switching and Porting for our main services across Google Cloud and Workspace. SWIPO is a European standard, but we apply it across these services globally to support customers worldwide. We see adherence to SWIPO as another opportunity to confirm our commitment to enhancing customer choice. This is an ongoing effort. We continue to work to improve our data export capabilities and adapt to the changing regulatory landscape. The upcoming EU Data Act aims to reduce vendor lock-in and make the cloud sector more dynamic. The proposal enhances the work done through SWIPO by introducing a mandate for providers to remove obstacles to switching cloud services. We believe the Data Act can help set the right objectives on cloud switching, and also can help address some of the challenges organizations face as they move to the cloud and engage in their own cloud transformations. Google is committed to supporting Europe’s ambition to build a fair and innovative cloud sector.The EU Cloud Code of ConductWe are always looking for ways to increase our accountability and compliance support for our customers. To this end, we adhere to the EU Cloud Code of Conduct, a set of requirements that enable cloud service providers to demonstrate their commitment to rigorous data protection standards that align to the GDPR. Google was one of the first cloud providers to support and adhere to the provisions of the code, following meaningful collaboration between the cloud computing community, the European Commission, and data protection authorities.What’s NextWe’ll continue to listen to our customers and key stakeholders across Europe who are setting policy and helping shape requirements for data security, privacy, and sovereignty. Our goal is to make Google the best possible place for sustainable, digital transformation for European organizations on their terms—and there is much more to come. To learn more about how we support customers’ compliance efforts, visit our Compliance Resource Center.Related ArticleHelping build the digital future. On Europe’s terms.Cloud computing is globally recognized as the single most effective, agile and scalable path to digitally transform and drive value creat…Read Article
Quelle: Google Cloud Platform

Microsoft Cost Management updates – August 2022

Whether you're a new student, a thriving startup, or the largest enterprise, you have financial constraints, and you need to know what you're spending, where, and how to plan for the future. Nobody wants a surprise when it comes to the bill, and this is where Microsoft Cost Management comes in.

We're always looking for ways to learn more about your challenges and how Microsoft Cost Management can help you better understand where you're accruing costs in the cloud, identify and prevent bad spending patterns, and optimize costs to empower you to do more with less. Here are a few of the latest improvements and updates based on your feedback:

Manage your MCA billing account across multiple tenants
What’s new in Cost Management
What is desktop as a service (DaaS) and how can it help your organization?
Migrate and modernize with Azure to power innovation across the entire digital estate
5 steps to prepare developers for cloud modernization
What's new in Cost Management Labs
New ways to save money with Microsoft Cloud
Documentation updates
Join the Microsoft Cost Management team

Let's dig into the details.

Manage your MCA billing account across multiple tenants

Many organizations have multiple Azure Active Directory tenants. They may have originated from mergers and acquisitions or were set up to separate environments for resources and applications. Regardless of the reason, you can now consolidate and manage all your Azure Active Directory tenants from a single Microsoft Customer Agreement (MCA) billing account.

To get started, configure associated tenants for your billing account from the Azure portal by navigating to Cost Management + Billing, then selecting Access control (IAM) in the menu, and selecting the Associated billing tenants command at the top of the screen.

Once the global admin for the tenant accepts the invitation, subscriptions can be moved to the billing account and you can provide users from that tenant access to your billing account, allowing them to perform activities like viewing and downloading invoices, monitoring cost, or creating subscriptions without having to switch tenants in the Azure portal, which has been common feedback we’ve heard about managing MCA billing accounts.

To learn more, see Manage billing across multiple tenants using associated billing tenants.

What's new in Cost Management

The cloud runs at break-neck speed and staying informed can be tough. That’s the primary reason we keep delivering these monthly updates to make it a little easier for you to see what’s new in Microsoft Cost Management. For those who aren’t regularly checking the blog, you can now see some of the latest Cost Management updates directly in the portal on the Cost Management overview.

Just a small thing to help you keep up to date on the latest developments. Let us know what you’d like to see next.

What is desktop as a service (DaaS) and how can it help your organization?

Today’s workers want the freedom to respond to email and collaborate with colleagues from anywhere, on any device—whether they’re working at their kitchen table, at the airport waiting for their flight to board, or in the carpool line waiting for their kids to get out of school. The pandemic proved that remote teams could succeed, no matter where they worked and how far-flung they were.

Even so, many companies are still scrambling to accommodate the technological needs of their hybrid and remote workers. Desktop as a service, sometimes known by the acronym DaaS, can help.

Read the full article to learn about desktop as a service and how it can help you reduce costs.

Migrate and modernize with Azure to power innovation across the entire digital estate

Cloud adoption increased significantly during COVID-19 and continues for many companies. However, an enormous migration and modernization opportunity remains as organizations continue their digital transformation. In fact, 72 percent of organizations reported their industry’s pace of digital transformation accelerated because of COVID-19, according to a survey sponsored by Microsoft in The Economist.

And we don’t expect that to slow down anytime soon.

Read the full article to learn more about the key themes we’re seeing and new programs, capabilities, and opportunities to help along the way.

5 steps to prepare developers for cloud modernization

If you’re thinking about what it takes to modernize your applications, you’re not alone. Companies everywhere now understand that migrating applications to the cloud and shifting to a cloud-first approach is critical to business competitiveness. The purpose of modernizing applications is to better align them to current and future business needs. By deploying enterprise applications to the cloud, you gain greater ability to innovate, improve security, scale to meet demand, manage costs, and deliver rich and consistent customer experiences anywhere in the world more quickly.

Read the full article on the Azure blog.

What's new in Cost Management Labs

With Cost Management Labs, you get a sneak peek at what's coming in Microsoft Cost Management and can engage directly with us to share feedback and help us better understand how you use the service, so we can deliver more tuned and optimized experiences. Here are a few features you can see in Cost Management Labs:

Updated: What’s new in Cost Management – Now available in the public portal.
Learn about new announcements from the Cost Management overview. You can opt-in using Try Preview.
Updated: Cost savings insights in the cost analysis preview – Now enabled by default in Labs.
Identify potential savings available from Azure Advisor cost recommendations for your Azure subscription. You can opt-in using Try preview.
Forecast in the cost analysis preview.
Show your forecast cost for the period at the top of the cost analysis preview. You can opt-in using Try preview.
Product column experiment in the cost analysis preview.
We’re testing new columns in the Resources and Services views in the cost analysis preview for Microsoft Customer Agreement. You may see a single Product column instead of the Service, Tier, and Meter columns. Please leave feedback to let us know which you prefer.
Group related resources in the cost analysis preview.
Group related resources, like disks under virtual machines or web apps under App Service plans, by adding a “cm-resource-parent” tag to the child resources with a value of the parent resource ID.
Charts in the cost analysis preview.
View your daily or monthly cost over time in the cost analysis preview. You can opt-in using Try Preview.
View cost for your resources.
The cost for your resources is one click away from the resource overview in the preview portal. Just click View cost to quickly jump to the cost of that resource.
Change scope from the menu.
Change scope from the menu for quicker navigation. You can opt-in using Try Preview.

Of course, that's not all. Every change in Microsoft Cost Management is available in Cost Management Labs a week before it's in the full Azure portal or Microsoft 365 admin center. We're eager to hear your thoughts and understand what you'd like to see next. What are you waiting for? Try Cost Management Labs today.

New ways to save money in the Microsoft Cloud

Lots of cost optimization improvements over the last month! Here are some of the generally available offers you might be interested in:

US West 3 price reduction.
Azure Public IPv6 offerings are free as of July 31, 2022.
AKS node pool user start/stop feature.
Reserved instance pricing for Azure Cache for Redis Enterprise.
NVads A10 v5 virtual machines.
Gateway Load Balancer.
Microsoft Azure available from new cloud region in Qatar.
Azure Log Analytics in China North 3 and China East 3.
Application Insights in China North 3 and China East 3.
Azure Stream Analytics in China East 3, China North 3, US DoD East, and US DoD Texas.
Azure Databricks in West US 3.

And here are a couple new previews:

AMD-based confidential VMs for Azure Kubernetes Service (AKS).
Azure Premium SSD v2 Disk Storage.
Serverless SQL for Azure Databricks.
App Configuration geo replication support.

Documentation updates

Lots of updates based on your feedback with a few new docs you might be interested in:

New: Calculate EA reservations cost savings.
New: Manage billing across multiple tenants.
New: Find tenant ID and primary domain.
Plus 14 updates based on your feedback.

Want to keep an eye on all documentation updates? Check out the Cost Management and Billing documentation change history in the azure-docs repository on GitHub. If you see something missing, select Edit at the top of the document and submit a quick pull request. You can also submit a GitHub issue. We welcome and appreciate all contributions!

Join the Microsoft Cost Management team

Are you excited about helping customers and partners better manage and optimize costs? We're looking for passionate, dedicated, and exceptional people to help build best-in-class cloud platforms and experiences to enable exactly that. If you have experience with big data infrastructure, reliable and scalable APIs, or rich and engaging user experiences, you'll find no better challenge than serving every Microsoft customer and partner in one of the most critical areas for driving cloud success.

Watch the video below to learn more about the Microsoft Cost Management team:

Join our team.

What's next?

These are just a few of the big updates from last month. Don't forget to check out the previous Microsoft Cost Management updates. We're always listening and making constant improvements based on your feedback, so please keep the feedback coming.

Follow @MSCostMgmt on Twitter and subscribe to the YouTube channel for updates, tips, and tricks. You can also share ideas and vote up others in the Cost Management feedback forum.

We know these are trying times for everyone. Best wishes from the Microsoft Cost Management team. Stay safe and stay healthy.
Quelle: Azure

Elevate your visualizations with Azure Managed Grafana—now generally available

As part of our continued commitment to open source solutions, we are announcing the general availability of Azure Managed Grafana, a managed service that enables you to run Grafana natively within the Azure cloud platform. With Azure Managed Grafana, you can seamlessly and securely connect with and scale to businesses’ existing Azure services, enhancing observability and cloud management.

In addition to the features announced during preview, with general availability, we’re introducing new capabilities that include the latest Grafana v9.0 features with its improved alerting experience as well as zone redundancy (in preview) and API key support.

New connections and integrations with Azure services

With general availability, we are adding new integrations with Azure services, allowing you to realize the benefits of Grafana as efficiently and effectively as possible.

We have introduced several new out-of-the-box dashboards for Azure Monitor. For example, with Availability Tests Geo Map dashboard for Azure Monitor application insights, you can view the results and responsiveness of your application availability tests based on geographic location. Additionally, with the new out-of-the-box Load Balancing dashboard for Azure Monitor network insights, you can monitor key performance metrics for all your Azure load balancing resources, including Load Balancers, Application Gateway, Front Door, and Traffic Manager.

The new “pin to Grafana” feature for Azure Monitor Logs allows you to seamlessly add charts and queries from Azure Monitor Logs to Grafana dashboards with just one click. In the illustration below, you can see how the Azure Monitor Logs query on the left is replicated in the Grafana interface on the right.

Similarly, we have introduced new out-of-the-box dashboards for Azure Container Apps as well. The new Aggregate View dashboard for Azure Container Apps depicts a geographic map of your container apps filtered by resource group, environment, and region with drill-down links to a detailed dashboard for each app. The new App View dashboard for Azure Container Apps monitors the performance of Azure Container Apps by viewing the key metrics of CPU, memory, restarts, and network traffic or by revision, replica, and status code.

Read the Azure Managed Grafana technical community blog to learn more about the latest enhancements.

Get started with Azure Managed Grafana

Try it free for the first 30 days from the Azure portal today.

Go to the Azure Managed Grafana product page.

Read the technical documentation.

Share feedback on Microsoft Q&A.
Quelle: Azure

How to Build and Run Next.js Applications with Docker, Compose, & NGINX

At DockerCon 2022, Kathleen Juell, a Full Stack Engineer at Sourcegraph, shared some tips for combining Next.js, Docker, and NGINX to serve static content. With nearly 400 million active websites today, efficient content delivery is key to attracting new web application users.

In some cases, using Next.js can boost deployment efficiency, accelerate time to market, and help attract web users. Follow along as we tackle building and running Next.js applications with Docker. We’ll also cover key processes and helpful practices for serving that static content. 

Why serve static content with a web application?

According to Kathleen, the following are the benefits of serving static content: 

Fewer moving parts, like databases or other microservices, directly impact page rendering. This backend simplicity minimizes attack surfaces. Static content stands up better (with fewer uncertainties) to higher traffic loads.Static websites are fast since they don’t require repeated rendering.Static website code is stable and relatively unchanging, improving scalability.Simpler content means more deployment options.

Since we know why building a static web app is beneficial, let’s explore how.

Building our services stack

To serve static content efficiently, a three-pronged services approach composed of Next.js, NGINX, and Docker is useful. While it’s possible to run a Next.js server, offloading those tasks to an NGINX server is preferable. NGINX is event-driven and excels at rapidly serving content thanks to its single-threaded architecture. This enables performance optimization even during periods of higher traffic.  

Luckily, containerizing a cross-platform NGINX server instance is pretty straightforward. This setup is also resource friendly. Below are some of the reasons why Kathleen — explicitly or perhaps implicitly — leveraged three technologies. 

Docker Desktop also gives us the tools needed to build and deploy our application. It’s important to install Docker Desktop before recreating Kathleen’s development process. 

The following trio of services will serve our static content:

First, our auth-backend has a build context rooted in a directory and a port mapping. It’s based on a slimmer alpine flavor of the Node.js Docker Official Image and uses named Dockerfile build stages to prevent reordered COPY instructions from breaking. 

Second, our client service has its own build context and a named volume mapped to the staticbuild:/app/out directory. This lets us mount our volume within our NGINX container. We’re not mapping any ports since NGINX will serve our content.

Third, we’ll containerize an NGINX server that’s based on the NGINX Docker Official Image.

As Kathleen mentions, ending this client service’s Dockerfile with a RUN command is key. We want the container to exit after completing the yarn build process. This process generates our static content and should only happen once for a static web application.

Each component is accounted for within its own container. Now, how do we seamlessly spin up this multi-container deployment and start serving content? Let’s dive in!

Using Docker Compose and Docker volumes

The simplest way to orchestrate multi-container deployments is with Docker Compose. This lets us define multiple services within a unified configuration, without having to juggle multiple files or write complex code. 

We use a compose.yml file to describe our services, their contexts, networks, ports, volumes, and more. These configurations influence app behavior. 

Here’s what our complete Docker Compose file looks like: 

services:
auth-backend:
build:
context: ./auth-backend
ports:
– "3001:3001"
networks:
– dev

client:
build:
context: ./client
volumes:
– staticbuild:/app/out
networks:
– dev

nginx:
build:
context: ./nginx
volumes:
– staticbuild:/app/public
ports:
– “8080:80”
networks:
– dev

networks:
dev:
driver: bridge

volumes:
staticbuild:

You’ll also see that we’ve defined our networks and volumes in this file. These services all share the dev network, which lets them communicate with each other while remaining discoverable. You’ll also see a common volume between these services. We’ll now explain why that’s significant.

Using mounted volumes to share files

Specifically, this example leverages named volumes to share files between containers. By mapping the staticbuild volume to Next.js’ default out directory location, you can export your build and serve content with your NGINX server. This typically exists as one or more HTML files. Note that NGINX uses the app/public directory by comparison. 

While Next.js helps present your content on the frontend, NGINX delivers those important resources from the backend. 

Leveraging A/B testing to create tailored user experiences

You can customize your client-side code to change your app’s appearance, and ultimately the end-user experience. This code impacts how page content is displayed while something like an NGINX server is running. It may also determine which users see which content — something that’s common based on sign-in status, for example. 

Testing helps us understand how application changes can impact these user experiences, both positively and negatively. A/B testing helps us uncover the “best” version of our application by comparing features and page designs. How does this look in practice? 

Specifically, you can use cookies and hooks to track user login activity. When a user logs in, they’ll see something like user stories (from Kathleen’s example). Logged-out users won’t see this content. Alternatively, a web user might only have access to certain pages once they’re authenticated. It’s your job to monitor user activity, review any feedback, and determine if those changes bring clear value. 

These are just two use cases for A/B testing, and the possibilities are nearly endless when it comes to conditionally rendering static content with Next.js. 

Containerize your Next.js static web app

There are many different ways to serve static content. However, Kathleen’s three-service method remains an excellent example. It’s useful both during exploratory testing and in production. To learn more, check out Kathleen’s complete talk. 

By containerizing each service, your application remains flexible and deployable across any platform. Docker can help developers craft accessible, customizable user experiences within their web applications. Get started with Next.js and Docker today to begin serving your static web content! 

Additional Resources

Check out the NGINX Docker Official ImageRead about the Node Docker Official ImageLearn about getting started with Docker ComposeView our awesome-compose sample GitHub projects
Quelle: https://blog.docker.com/feed/

August 2022 Newsletter

Community All-Hands: September 1st
Join us tomorrow at our Community All-Hands on September 1st! This virtual event is an opportunity for the community to come together with Docker staff to learn, share, and collaborate. Don’t miss your opportunity to win Docker swag!

Register Now

News you can use and monthly highlights:
6 Docker Compose Best Practices for Dev and Prod – Give your development team a quick knowledge boost with these tips and best practices for using Docker Compose in development and production environments.
Docker Multistage Builds for Hugo – Learn how to keep your Docker container images nice and slim with the use of multistage builds for a hugo documentation project.
How to create a dockerized Nuxt 3 development environment – Learn how Docker simplifies and accelerates the Nuxt.js development workflow. It can also help you build a bleeding-edge, local web app while ensuring consistency between development and production.
Optimize Dockerfile images for NextJS – Is the size of your Next.js Docker image impacting your overall CI/CD pipeline? Here’s an article that’ll help you to improve the development and production lifecycle by optimizing your Docker images efficiently.
Building and Testing Multi-Arch Images with Docker Buildx and QEMU – Building Docker images for multiple architectures has become increasingly popular. This guide walks you through how to build a Docker image for linux/amd64 and linux/arm64 using Docker Buildx. It’ll also walk you through using QEMU to emulate an ARM environment for multiple platform builds.
Implementation And Containerization Of Microservices Using .NET Core 6 And Docker – This article helps you create microservices using the .NET Core 6 Web API and Docker. It’ll also walk you through how to connect them using Ocelot API Gateway.​

Testing with Telepresence
Wishing for a way to synchronize local changes with a remote Kubernetes environment? There is a Docker Extension for that! Learn how Telepresence partners with Docker Desktop to help you run integration tests quickly and where to get started.

Learn More

The latest tips and tricks from the community:

How to Build and Deploy a Task Management Application Using Go
Containerizing a Legendary PetClinic App Built with Spring Boot
Build and Deploy a Retail Store Items Detection System Using No-Code AI Vision at the Edge
Slim.AI Docker Extension for Docker Desktop

Dear Moby: Advice for developers
Looking for developer-specific advice and insights? Introducing our Dear Moby collection — a web series and advice column inspired by and made for YOU, our Docker community. Check out the show, read the column, and submit your app dev questions here.

Watch Dear Moby

Educational content created by the experts at Docker:

How I Built My First Containerized Java Web Application
How to Use the Apache httpd Docker Official Image
How to Use the Redis Docker Official Image
How to Develop and Deploy a Customer Churn Prediction Model Using Python, Streamlit, and Docker

Docker Captain: Julien Maitrehenry
Julien has been working with Docker since 2014 and is now joining as a Docker Captain! His friends call him “Mister Docker” because he’s always sharing his knowledge with others. Julien’s top tip for working with Docker is to build cross-platform images.

Meet the Captain

See what the Docker team has been up to:

Bulk User Add for Docker Business and Teams
Virtual Desktop Support, Mac Permission Changes, & New Extensions in Docker Desktop 4.11
Demo: Managing and Securing Your Docker Workflows
Conversation with RedMonk: Developer Engagement in the Remote Work Era

Docker Hub v1 API deprecation
On September 5th, 2022, Docker plans to deprecate the Docker Hub v1 API endpoints that access information related to Docker Hub repositories. Please update to the v2 endpoints to continue using the Docker Hub API.

Learn More

Subscribe to our newsletter to get the latest news, blogs, tips, how-to guides, best practices, and more from Docker experts sent directly to your inbox once a month.

Quelle: https://blog.docker.com/feed/

Amazon SageMaker ist jetzt in der AWS-Region Asien-Pazifik (Jakarta) verfügbar

Amazon SageMaker ist jetzt in der AWS-Region Asien-Pazifik (Jakarta) verfügbar. Amazon SageMaker ist ein vollständig verwalteter Service, der jedem Entwickler und Daten-Wissenschaftler die Möglichkeit bietet, schnell Modelle für Machine Learning (ML) zu erstellen, zu schulen und bereitzustellen. SageMaker beseitigt die Schwierigkeiten und den Aufwand bei jedem Schritt des Machine-Learning-Prozesses, um die Entwicklung hochwertiger Modelle zu vereinfachen.
Quelle: aws.amazon.com

Amazon-RDS unterstützt jetzt die Einrichtung einer Verbindung zwischen deiner RDS-Datenbank und deiner EC2-Compute-Instance mit nur einem Klick

Ab heute hast du die Möglichkeit, während der Datenbankerstellung die Verbindung automatisch von den Amazon-RDS (Amazon-Relational-Database-Service) und Amazon-Aurora-Datenbanken zu einer Amazon-EC2 (Amazon-Elastic-Compute-Cloud) Compute-Instance zu ändern. Wenn du eine Datenbank mit der Amazon-RDS-Konsole bereitstellst, ist es jetzt möglich eine EC2-Instance auszuwählen, und mit nur einem Klick die Verbindung zwischen der Datenbank und der EC2-Instance herzustellen, den von AWS empfohlenen bewährten Methoden folgend. Amazon-RDS richtet während der Datenbankerstellung deine VPC- und ähnliche Netzwerkeinstellungen automatisch ein, um eine sichere Verbindung zwischen der EC2-Instance und der RDS-Datenbank herzustellen.
Quelle: aws.amazon.com

Einführung einer API von Amazon-Connect, um per Berechtigung, Beschreibung und Tags nach Sicherheitsprofilen zu suchen

Amazon-Connect bietet nun eine neue API zur Suche nach Sicherheitsprofilen in deiner Amazon-Connect-Instance an. Diese neue API stellt eine programmgesteuerte und flexible Möglichkeit für die Suche nach Sicherheitsprofilen mit Name, Beschreibung, Berechtigungen oder Tags, bereit. Du kannst diese API jetzt benutzen, um z. B. nach allen Sicherheitsprofilen zu suchen, welche über die Berechtigung verfügen, Kontaktabläufe zu bearbeiten. Weitere Informationen zu dieser neuen API findest du in der API-Dokumentation.
Quelle: aws.amazon.com