The aws:m2/environment:Environment resource, part of the Pulumi AWS provider, provisions the runtime infrastructure for AWS Mainframe Modernization applications: compute instances, networking, and optional storage. This guide focuses on three capabilities: engine type and instance sizing, high availability configuration, and EFS and FSX storage attachment.
Mainframe Modernization environments run in VPC subnets with security groups and may mount EFS or FSX filesystems. The examples are intentionally small. Combine them with your own VPC infrastructure and storage resources.
Create a runtime environment for mainframe applications
Mainframe Modernization environments provide the runtime for migrated COBOL or PL/I applications. Start by defining the engine type, instance size, and network placement.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.m2.Environment("test", {
name: "test-env",
engineType: "bluage",
instanceType: "M2.m5.large",
securityGroups: ["sg-01234567890abcdef"],
subnetIds: [
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
});
import pulumi
import pulumi_aws as aws
test = aws.m2.Environment("test",
name="test-env",
engine_type="bluage",
instance_type="M2.m5.large",
security_groups=["sg-01234567890abcdef"],
subnet_ids=[
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/m2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := m2.NewEnvironment(ctx, "test", &m2.EnvironmentArgs{
Name: pulumi.String("test-env"),
EngineType: pulumi.String("bluage"),
InstanceType: pulumi.String("M2.m5.large"),
SecurityGroups: []string{
"sg-01234567890abcdef",
},
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-01234567890abcdef"),
pulumi.String("subnet-01234567890abcdea"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.M2.Environment("test", new()
{
Name = "test-env",
EngineType = "bluage",
InstanceType = "M2.m5.large",
SecurityGroups = new[]
{
"sg-01234567890abcdef",
},
SubnetIds = new[]
{
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.m2.Environment;
import com.pulumi.aws.m2.EnvironmentArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var test = new Environment("test", EnvironmentArgs.builder()
.name("test-env")
.engineType("bluage")
.instanceType("M2.m5.large")
.securityGroups(List.of("sg-01234567890abcdef"))
.subnetIds(
"subnet-01234567890abcdef",
"subnet-01234567890abcdea")
.build());
}
}
resources:
test:
type: aws:m2:Environment
properties:
name: test-env
engineType: bluage
instanceType: M2.m5.large
securityGroups:
- sg-01234567890abcdef
subnetIds:
- subnet-01234567890abcdef
- subnet-01234567890abcdea
The engineType property specifies which modernization engine to use: “bluage” for COBOL applications or “microfocus” for PL/I workloads. The instanceType determines compute capacity. The environment runs in your specified subnets with attached security groups, which control network access to and from the instances.
Enable high availability with multiple instances
Production workloads require redundancy to handle instance failures without downtime.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.m2.Environment("test", {
name: "test-env",
engineType: "bluage",
instanceType: "M2.m5.large",
securityGroups: ["sg-01234567890abcdef"],
subnetIds: [
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
highAvailabilityConfig: {
desiredCapacity: 2,
},
});
import pulumi
import pulumi_aws as aws
test = aws.m2.Environment("test",
name="test-env",
engine_type="bluage",
instance_type="M2.m5.large",
security_groups=["sg-01234567890abcdef"],
subnet_ids=[
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
high_availability_config={
"desired_capacity": 2,
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/m2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := m2.NewEnvironment(ctx, "test", &m2.EnvironmentArgs{
Name: pulumi.String("test-env"),
EngineType: pulumi.String("bluage"),
InstanceType: pulumi.String("M2.m5.large"),
SecurityGroups: []string{
"sg-01234567890abcdef",
},
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-01234567890abcdef"),
pulumi.String("subnet-01234567890abcdea"),
},
HighAvailabilityConfig: &m2.EnvironmentHighAvailabilityConfigArgs{
DesiredCapacity: pulumi.Int(2),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.M2.Environment("test", new()
{
Name = "test-env",
EngineType = "bluage",
InstanceType = "M2.m5.large",
SecurityGroups = new[]
{
"sg-01234567890abcdef",
},
SubnetIds = new[]
{
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
},
HighAvailabilityConfig = new Aws.M2.Inputs.EnvironmentHighAvailabilityConfigArgs
{
DesiredCapacity = 2,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.m2.Environment;
import com.pulumi.aws.m2.EnvironmentArgs;
import com.pulumi.aws.m2.inputs.EnvironmentHighAvailabilityConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var test = new Environment("test", EnvironmentArgs.builder()
.name("test-env")
.engineType("bluage")
.instanceType("M2.m5.large")
.securityGroups(List.of("sg-01234567890abcdef"))
.subnetIds(
"subnet-01234567890abcdef",
"subnet-01234567890abcdea")
.highAvailabilityConfig(EnvironmentHighAvailabilityConfigArgs.builder()
.desiredCapacity(2)
.build())
.build());
}
}
resources:
test:
type: aws:m2:Environment
properties:
name: test-env
engineType: bluage
instanceType: M2.m5.large
securityGroups:
- sg-01234567890abcdef
subnetIds:
- subnet-01234567890abcdef
- subnet-01234567890abcdea
highAvailabilityConfig:
desiredCapacity: 2
The highAvailabilityConfig property spreads the environment across multiple instances. The desiredCapacity sets how many instances to maintain. For true high availability, provide subnets in different availability zones so AWS can distribute instances across failure domains.
Attach EFS for shared persistent storage
Applications that need shared file access across instances or persistent data beyond instance lifecycles can mount an EFS filesystem.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.m2.Environment("test", {
name: "test-env",
engineType: "bluage",
instanceType: "M2.m5.large",
securityGroups: ["sg-01234567890abcdef"],
subnetIds: [
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
storageConfiguration: {
efs: {
fileSystemId: "fs-01234567890abcdef",
mountPoint: "/m2/mount/example",
},
},
});
import pulumi
import pulumi_aws as aws
test = aws.m2.Environment("test",
name="test-env",
engine_type="bluage",
instance_type="M2.m5.large",
security_groups=["sg-01234567890abcdef"],
subnet_ids=[
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
storage_configuration={
"efs": {
"file_system_id": "fs-01234567890abcdef",
"mount_point": "/m2/mount/example",
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/m2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := m2.NewEnvironment(ctx, "test", &m2.EnvironmentArgs{
Name: pulumi.String("test-env"),
EngineType: pulumi.String("bluage"),
InstanceType: pulumi.String("M2.m5.large"),
SecurityGroups: []string{
"sg-01234567890abcdef",
},
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-01234567890abcdef"),
pulumi.String("subnet-01234567890abcdea"),
},
StorageConfiguration: &m2.EnvironmentStorageConfigurationArgs{
Efs: &m2.EnvironmentStorageConfigurationEfsArgs{
FileSystemId: pulumi.String("fs-01234567890abcdef"),
MountPoint: pulumi.String("/m2/mount/example"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.M2.Environment("test", new()
{
Name = "test-env",
EngineType = "bluage",
InstanceType = "M2.m5.large",
SecurityGroups = new[]
{
"sg-01234567890abcdef",
},
SubnetIds = new[]
{
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
},
StorageConfiguration = new Aws.M2.Inputs.EnvironmentStorageConfigurationArgs
{
Efs = new Aws.M2.Inputs.EnvironmentStorageConfigurationEfsArgs
{
FileSystemId = "fs-01234567890abcdef",
MountPoint = "/m2/mount/example",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.m2.Environment;
import com.pulumi.aws.m2.EnvironmentArgs;
import com.pulumi.aws.m2.inputs.EnvironmentStorageConfigurationArgs;
import com.pulumi.aws.m2.inputs.EnvironmentStorageConfigurationEfsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var test = new Environment("test", EnvironmentArgs.builder()
.name("test-env")
.engineType("bluage")
.instanceType("M2.m5.large")
.securityGroups(List.of("sg-01234567890abcdef"))
.subnetIds(
"subnet-01234567890abcdef",
"subnet-01234567890abcdea")
.storageConfiguration(EnvironmentStorageConfigurationArgs.builder()
.efs(EnvironmentStorageConfigurationEfsArgs.builder()
.fileSystemId("fs-01234567890abcdef")
.mountPoint("/m2/mount/example")
.build())
.build())
.build());
}
}
resources:
test:
type: aws:m2:Environment
properties:
name: test-env
engineType: bluage
instanceType: M2.m5.large
securityGroups:
- sg-01234567890abcdef
subnetIds:
- subnet-01234567890abcdef
- subnet-01234567890abcdea
storageConfiguration:
efs:
fileSystemId: fs-01234567890abcdef
mountPoint: /m2/mount/example
The storageConfiguration property’s efs block connects an existing EFS filesystem to the environment. The fileSystemId references your filesystem, and mountPoint specifies where it appears in the instance filesystem. All instances in the environment share the same mounted storage.
Attach FSX for Windows-compatible storage
Some mainframe applications require Windows-compatible file systems or need FSX’s performance characteristics.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.m2.Environment("test", {
name: "test-env",
engineType: "bluage",
instanceType: "M2.m5.large",
securityGroups: ["sg-01234567890abcdef"],
subnetIds: [
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
storageConfiguration: {
fsx: {
fileSystemId: "fs-01234567890abcdef",
mountPoint: "/m2/mount/example",
},
},
});
import pulumi
import pulumi_aws as aws
test = aws.m2.Environment("test",
name="test-env",
engine_type="bluage",
instance_type="M2.m5.large",
security_groups=["sg-01234567890abcdef"],
subnet_ids=[
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
],
storage_configuration={
"fsx": {
"file_system_id": "fs-01234567890abcdef",
"mount_point": "/m2/mount/example",
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/m2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := m2.NewEnvironment(ctx, "test", &m2.EnvironmentArgs{
Name: pulumi.String("test-env"),
EngineType: pulumi.String("bluage"),
InstanceType: pulumi.String("M2.m5.large"),
SecurityGroups: []string{
"sg-01234567890abcdef",
},
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-01234567890abcdef"),
pulumi.String("subnet-01234567890abcdea"),
},
StorageConfiguration: &m2.EnvironmentStorageConfigurationArgs{
Fsx: &m2.EnvironmentStorageConfigurationFsxArgs{
FileSystemId: pulumi.String("fs-01234567890abcdef"),
MountPoint: pulumi.String("/m2/mount/example"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.M2.Environment("test", new()
{
Name = "test-env",
EngineType = "bluage",
InstanceType = "M2.m5.large",
SecurityGroups = new[]
{
"sg-01234567890abcdef",
},
SubnetIds = new[]
{
"subnet-01234567890abcdef",
"subnet-01234567890abcdea",
},
StorageConfiguration = new Aws.M2.Inputs.EnvironmentStorageConfigurationArgs
{
Fsx = new Aws.M2.Inputs.EnvironmentStorageConfigurationFsxArgs
{
FileSystemId = "fs-01234567890abcdef",
MountPoint = "/m2/mount/example",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.m2.Environment;
import com.pulumi.aws.m2.EnvironmentArgs;
import com.pulumi.aws.m2.inputs.EnvironmentStorageConfigurationArgs;
import com.pulumi.aws.m2.inputs.EnvironmentStorageConfigurationFsxArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var test = new Environment("test", EnvironmentArgs.builder()
.name("test-env")
.engineType("bluage")
.instanceType("M2.m5.large")
.securityGroups(List.of("sg-01234567890abcdef"))
.subnetIds(
"subnet-01234567890abcdef",
"subnet-01234567890abcdea")
.storageConfiguration(EnvironmentStorageConfigurationArgs.builder()
.fsx(EnvironmentStorageConfigurationFsxArgs.builder()
.fileSystemId("fs-01234567890abcdef")
.mountPoint("/m2/mount/example")
.build())
.build())
.build());
}
}
resources:
test:
type: aws:m2:Environment
properties:
name: test-env
engineType: bluage
instanceType: M2.m5.large
securityGroups:
- sg-01234567890abcdef
subnetIds:
- subnet-01234567890abcdef
- subnet-01234567890abcdea
storageConfiguration:
fsx:
fileSystemId: fs-01234567890abcdef
mountPoint: /m2/mount/example
The fsx block works like the efs block but connects an FSX filesystem instead. FSX provides Windows-compatible storage and different performance profiles than EFS. Only one storage type (EFS or FSX) can be configured per environment.
Beyond these examples
These snippets focus on specific environment-level features: engine and instance type selection, high availability configuration, and EFS and FSX storage attachment. They’re intentionally minimal rather than full mainframe migration solutions.
The examples reference pre-existing infrastructure such as VPC subnets and security groups, and EFS or FSX filesystems for storage examples. They focus on configuring the environment rather than provisioning the surrounding infrastructure.
To keep things focused, common environment patterns are omitted, including:
- Public accessibility controls (publiclyAccessible)
- KMS encryption (kmsKeyId)
- Maintenance window scheduling (preferredMaintenanceWindow)
- Force update behavior (forceUpdate)
These omissions are intentional: the goal is to illustrate how each environment feature is wired, not provide drop-in mainframe modules. See the Mainframe Modernization Environment resource reference for all available configuration options.
Let's create AWS Mainframe Modernization Environments
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Setup
name, engineType, engineVersion, instanceType, securityGroupIds, subnetIds, publiclyAccessible, and preferredMaintenanceWindow. The name must be unique within your AWS account.engineType must be either microfocus or bluage.ddd:hh24:mi-ddd:hh24:mi (e.g., sun:05:00-sun:09:00) and ensure the duration is less than 24 hours. If not provided, a random value will be used.Storage & Persistence
storageConfiguration. For EFS, provide efs.fileSystemId and efs.mountPoint. For FSX, provide fsx.fileSystemId and fsx.mountPoint.kmsKeyId parameter with the ARN of your KMS key.High Availability & Maintenance
highAvailabilityConfig with desiredCapacity set to 2 or higher to enable high availability.forceUpdate to true to force updates even when applications are running.Networking & Access
publiclyAccessible to true to allow applications deployed to this environment to be publicly accessible.securityGroupIds (list of security group IDs) and subnetIds (list of subnet IDs) to deploy the environment into your VPC.loadBalancerArn is a computed output property available after the environment is created.