Repository: pulumi/pulumi-awsx (ts)

Issue:
Impossible to create an EC2Service with networkmode other than awsvpc
### What happened?

networkMode is hardcoded [here](https://github.com/pulumi/pulumi-awsx/blob/master/awsx/ecs/ec2TaskDefinition.ts#L127).

Additionally (related) networkConfiguration is required in all cases, contrary to the documentation https://github.com/pulumi/pulumi-awsx/blob/master/awsx/schema.json#L2056 

### Steps to reproduce

Consider this test
```ts
// Copyright 2016-2022, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import * as pulumi from "@pulumi/pulumi";

import { EC2TaskDefinition } from "./ec2TaskDefinition";

function promiseOf<T>(output: pulumi.Output<T>): Promise<T> {
  return new Promise((resolve) => output.apply(resolve));
}

describe("validateNetworkMode", () => {
  beforeAll(() => {
    // Put Pulumi in unit-test mode, mocking all calls to cloud-provider APIs.
    pulumi.runtime.setMocks({
      // Mock calls to create new resources and return a canned response.
      newResource: (args: pulumi.runtime.MockResourceArgs): { id: string; state: any } => {
        // Here, we're returning a same-shaped object for all resource types.
        // We could, however, use the arguments passed into this function to
        // customize the mocked-out properties of a particular resource.
        // See the unit-testing docs for details:
        // https://www.pulumi.com/docs/guides/testing/unit
        return {
          id: `${args.name}-id`,
          state: args.inputs,
        };
      },

      // Mock function calls and return whatever input properties were provided.
      call: (args: pulumi.runtime.MockCallArgs) => {
        return args.inputs;
      },
    });
  });

  it("the default network mode should be awsvpc", async () => {
    const taskDefinition = new EC2TaskDefinition("default", {
      container: {},
    });
    const networkMode = await promiseOf(taskDefinition.taskDefinition.networkMode);
    expect(networkMode).toBe("awsvpc");
  });
  it("when network mode is set, use it", async () => {
    const taskDefinition = new EC2TaskDefinition("default", {
      container: {},
      networkMode: "bridge",
    });
    const networkMode = await promiseOf(taskDefinition.taskDefinition.networkMode);
    expect(networkMode).toBe("bridge");
  });
});

```

### Expected Behavior

When you set networkMode to "bridge" it's expected to use it. networkConfiguration should not be required in this case.

### Actual Behavior

awsvpc is always used.

### Output of `pulumi about`

```
CLI          
Version      3.46.1
Go Version   go1.19.3
Go Compiler  gc

Plugins
NAME    VERSION
aws     5.18.0
awsx    1.0.0-beta.11
docker  3.2.0
go      unknown

Host     
OS       arch
Version  
Arch     x86_64

This project is written in go: executable='/usr/bin/go' version='go version go1.19.3 linux/amd64'

Backend        
Name           pulumi.com
URL            https://app.pulumi.com/ekini
User           ekini
Organizations  ekini

Dependencies:
NAME                                 VERSION
github.com/imdario/mergo             0.3.12
github.com/pulumi/pulumi-aws/sdk/v5  5.18.0
github.com/pulumi/pulumi-awsx/sdk    1.0.0-beta.11
github.com/pulumi/pulumi/sdk/v3      3.44.2
github.com/stretchr/testify          1.7.1
go.mozilla.org/sops/v3               3.7.3
gopkg.in/yaml.v2                     2.4.0
```

### Additional context

_No response_

### Contributing

Vote on this issue by adding a 👍 reaction. 
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already). 


Pull request description:
Allow overriding of networkMode
Fixes #942

Possible breaking change for Go users as it changes the type?

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72bd88f0..abea86f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ CHANGELOG
 * Add multi-lang component support scaffolding.
 * Fix type errors in TypeScript checking awsx-classic properties.
 * Ensure that FargateService and EC2Service default `continueBeforeSteadyState` to false.
+* Make networkMode property usable for `ecs.Ec2TaskDefinition`.
 
 ## 0.40.0 (2022-03-24)
 * Compatibility with pulumi-aws v5.0.0
diff --git a/awsx/ecs/ec2TaskDefinition.ts b/awsx/ecs/ec2TaskDefinition.ts
index 5fccce93..6ff00d93 100644
--- a/awsx/ecs/ec2TaskDefinition.ts
+++ b/awsx/ecs/ec2TaskDefinition.ts
@@ -122,9 +122,9 @@ function buildTaskDefinitionArgs(
   const family = utils.ifUndefined(args.family, defaultFamily);
 
   return {
+    networkMode: "awsvpc",
     ...mutableArgs,
     requiresCompatibilities: ["EC2"],
-    networkMode: "awsvpc",
     taskRoleArn: taskRoleArn,
     executionRoleArn: executionRoleArn,
     family,
diff --git a/awsx/schema-types.ts b/awsx/schema-types.ts
index 22af4d51..102d4c72 100644
--- a/awsx/schema-types.ts
+++ b/awsx/schema-types.ts
@@ -152,7 +152,7 @@ export interface EC2ServiceArgs {
     readonly iamRole?: pulumi.Input<string>;
     readonly loadBalancers?: pulumi.Input<pulumi.Input<aws.types.input.ecs.ServiceLoadBalancer>[]>;
     readonly name?: pulumi.Input<string>;
-    readonly networkConfiguration: pulumi.Input<aws.types.input.ecs.ServiceNetworkConfiguration>;
+    readonly networkConfiguration?: pulumi.Input<aws.types.input.ecs.ServiceNetworkConfiguration>;
     readonly orderedPlacementStrategies?: pulumi.Input<pulumi.Input<aws.types.input.ecs.ServiceOrderedPlacementStrategy>[]>;
     readonly placementConstraints?: pulumi.Input<pulumi.Input<aws.types.input.ecs.ServicePlacementConstraint>[]>;
     readonly platformVersion?: pulumi.Input<string>;
diff --git a/awsx/schema.json b/awsx/schema.json
index 6c56b5db..1793747c 100644
--- a/awsx/schema.json
+++ b/awsx/schema.json
@@ -2102,9 +2102,6 @@
                     "description": "The args of task definition that you want to run in your service. Either [taskDefinition] or [taskDefinitionArgs] must be provided."
                 }
             },
-            "requiredInputs": [
-                "networkConfiguration"
-            ],
             "isComponent": true
         },
         "awsx:ecs:EC2TaskDefinition": {
diff --git a/schemagen/pkg/gen/ecsx.go b/schemagen/pkg/gen/ecsx.go
index c1d6d511..f25b61ae 100644
--- a/schemagen/pkg/gen/ecsx.go
+++ b/schemagen/pkg/gen/ecsx.go
@@ -104,7 +104,7 @@ func ec2Service(awsSpec schema.PackageSpec) schema.ResourceSpec {
 			Required: []string{"service"},
 		},
 		InputProperties: inputProperties,
-		RequiredInputs:  []string{"networkConfiguration"},
+		RequiredInputs:  []string{},
 	}
 }
 
diff --git a/sdk/dotnet/Ecs/EC2Service.cs b/sdk/dotnet/Ecs/EC2Service.cs
index a8da57bb..149fec05 100644
--- a/sdk/dotnet/Ecs/EC2Service.cs
+++ b/sdk/dotnet/Ecs/EC2Service.cs
@@ -36,7 +36,7 @@ namespace Pulumi.Awsx.Ecs
         /// <param name="name">The unique name of the resource</param>
         /// <param name="args">The arguments used to populate this resource's properties</param>
         /// <param name="options">A bag of options that control this resource's behavior</param>
-        public EC2Service(string name, EC2ServiceArgs args, ComponentResourceOptions? options = null)
+        public EC2Service(string name, EC2ServiceArgs? args = null, ComponentResourceOptions? options = null)
             : base("awsx:ecs:EC2Service", name, args ?? new EC2ServiceArgs(), MakeResourceOptions(options, ""), remote: true)
         {
         }
@@ -149,8 +149,8 @@ namespace Pulumi.Awsx.Ecs
         /// <summary>
         /// Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
         /// </summary>
-        [Input("networkConfiguration", required: true)]
-        public Input<Pulumi.Aws.Ecs.Inputs.ServiceNetworkConfigurationArgs> NetworkConfiguration { get; set; } = null!;
+        [Input("networkConfiguration")]
+        public Input<Pulumi.Aws.Ecs.Inputs.ServiceNetworkConfigurationArgs>? NetworkConfiguration { get; set; }
 
         [Input("orderedPlacementStrategies")]
         private InputList<Pulumi.Aws.Ecs.Inputs.ServiceOrderedPlacementStrategyArgs>? _orderedPlacementStrategies;
diff --git a/sdk/go/awsx/ecs/ec2service.go b/sdk/go/awsx/ecs/ec2service.go
index 6f0dc0b2..206d5629 100644
--- a/sdk/go/awsx/ecs/ec2service.go
+++ b/sdk/go/awsx/ecs/ec2service.go
@@ -7,7 +7,6 @@ import (
 	"context"
 	"reflect"
 
-	"github.com/pkg/errors"
 	"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/ecs"
 	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
 )
@@ -27,12 +26,9 @@ type EC2Service struct {
 func NewEC2Service(ctx *pulumi.Context,
 	name string, args *EC2ServiceArgs, opts ...pulumi.ResourceOption) (*EC2Service, error) {
 	if args == nil {
-		return nil, errors.New("missing one or more required arguments")
+		args = &EC2ServiceArgs{}
 	}
 
-	if args.NetworkConfiguration == nil {
-		return nil, errors.New("invalid value for required argument 'NetworkConfiguration'")
-	}
 	var resource EC2Service
 	err := ctx.RegisterRemoteComponentResource("awsx:ecs:EC2Service", name, args, &resource, opts...)
 	if err != nil {
@@ -71,7 +67,7 @@ type ec2serviceArgs struct {
 	// Name of the service (up to 255 letters, numbers, hyphens, and underscores)
 	Name *string `pulumi:"name"`
 	// Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
-	NetworkConfiguration ecs.ServiceNetworkConfiguration `pulumi:"networkConfiguration"`
+	NetworkConfiguration *ecs.ServiceNetworkConfiguration `pulumi:"networkConfiguration"`
 	// Service level strategy rules that are taken into consideration during task placement. List from top to bottom in order of precedence. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. The maximum number of `ordered_placement_strategy` blocks is `5`. See below.
 	OrderedPlacementStrategies []ecs.ServiceOrderedPlacementStrategy `pulumi:"orderedPlacementStrategies"`
 	// Rules that are taken into consideration during task placement. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. Maximum number of `placement_constraints` is `10`. See below.
@@ -123,7 +119,7 @@ type EC2ServiceArgs struct {
 	// Name of the service (up to 255 letters, numbers, hyphens, and underscores)
 	Name pulumi.StringPtrInput
 	// Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
-	NetworkConfiguration ecs.ServiceNetworkConfigurationInput
+	NetworkConfiguration ecs.ServiceNetworkConfigurationPtrInput
 	// Service level strategy rules that are taken into consideration during task placement. List from top to bottom in order of precedence. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. The maximum number of `ordered_placement_strategy` blocks is `5`. See below.
 	OrderedPlacementStrategies ecs.ServiceOrderedPlacementStrategyArrayInput
 	// Rules that are taken into consideration during task placement. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. Maximum number of `placement_constraints` is `10`. See below.
diff --git a/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2Service.java b/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2Service.java
index c34b7167..13c62593 100644
--- a/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2Service.java
+++ b/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2Service.java
@@ -62,7 +62,7 @@ public class EC2Service extends com.pulumi.resources.ComponentResource {
      * @param name The _unique_ name of the resulting resource.
      * @param args The arguments to use to populate this resource's properties.
      */
-    public EC2Service(String name, EC2ServiceArgs args) {
+    public EC2Service(String name, @Nullable EC2ServiceArgs args) {
         this(name, args, null);
     }
     /**
@@ -71,7 +71,7 @@ public class EC2Service extends com.pulumi.resources.ComponentResource {
      * @param args The arguments to use to populate this resource's properties.
      * @param options A bag of options that control this resource's behavior.
      */
-    public EC2Service(String name, EC2ServiceArgs args, @Nullable com.pulumi.resources.ComponentResourceOptions options) {
+    public EC2Service(String name, @Nullable EC2ServiceArgs args, @Nullable com.pulumi.resources.ComponentResourceOptions options) {
         super("awsx:ecs:EC2Service", name, args == null ? EC2ServiceArgs.Empty : args, makeResourceOptions(options, Codegen.empty()), true);
     }
 
diff --git a/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2ServiceArgs.java b/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2ServiceArgs.java
index 461434d5..8e67108f 100644
--- a/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2ServiceArgs.java
+++ b/sdk/java/src/main/java/com/pulumi/awsx/ecs/EC2ServiceArgs.java
@@ -241,15 +241,15 @@ public final class EC2ServiceArgs extends com.pulumi.resources.ResourceArgs {
      * Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
      * 
      */
-    @Import(name="networkConfiguration", required=true)
-    private Output<ServiceNetworkConfigurationArgs> networkConfiguration;
+    @Import(name="networkConfiguration")
+    private @Nullable Output<ServiceNetworkConfigurationArgs> networkConfiguration;
 
     /**
      * @return Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
      * 
      */
-    public Output<ServiceNetworkConfigurationArgs> networkConfiguration() {
-        return this.networkConfiguration;
+    public Optional<Output<ServiceNetworkConfigurationArgs>> networkConfiguration() {
+        return Optional.ofNullable(this.networkConfiguration);
     }
 
     /**
@@ -744,7 +744,7 @@ public final class EC2ServiceArgs extends com.pulumi.resources.ResourceArgs {
          * @return builder
          * 
          */
-        public Builder networkConfiguration(Output<ServiceNetworkConfigurationArgs> networkConfiguration) {
+        public Builder networkConfiguration(@Nullable Output<ServiceNetworkConfigurationArgs> networkConfiguration) {
             $.networkConfiguration = networkConfiguration;
             return this;
         }
@@ -959,7 +959,6 @@ public final class EC2ServiceArgs extends com.pulumi.resources.ResourceArgs {
         }
 
         public EC2ServiceArgs build() {
-            $.networkConfiguration = Objects.requireNonNull($.networkConfiguration, "expected parameter 'networkConfiguration' to be non-null");
             return $;
         }
     }
diff --git a/sdk/nodejs/ecs/ec2service.ts b/sdk/nodejs/ecs/ec2service.ts
index e5fe286b..e177834f 100644
--- a/sdk/nodejs/ecs/ec2service.ts
+++ b/sdk/nodejs/ecs/ec2service.ts
@@ -42,13 +42,10 @@ export class EC2Service extends pulumi.ComponentResource {
      * @param args The arguments to use to populate this resource's properties.
      * @param opts A bag of options that control this resource's behavior.
      */
-    constructor(name: string, args: EC2ServiceArgs, opts?: pulumi.ComponentResourceOptions) {
+    constructor(name: string, args?: EC2ServiceArgs, opts?: pulumi.ComponentResourceOptions) {
         let resourceInputs: pulumi.Inputs = {};
         opts = opts || {};
         if (!opts.id) {
-            if ((!args || args.networkConfiguration === undefined) && !opts.urn) {
-                throw new Error("Missing required property 'networkConfiguration'");
-            }
             resourceInputs["cluster"] = args ? args.cluster : undefined;
             resourceInputs["continueBeforeSteadyState"] = args ? args.continueBeforeSteadyState : undefined;
             resourceInputs["deploymentCircuitBreaker"] = args ? args.deploymentCircuitBreaker : undefined;
@@ -146,7 +143,7 @@ export interface EC2ServiceArgs {
     /**
      * Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
      */
-    networkConfiguration: pulumi.Input<pulumiAws.types.input.ecs.ServiceNetworkConfiguration>;
+    networkConfiguration?: pulumi.Input<pulumiAws.types.input.ecs.ServiceNetworkConfiguration>;
     /**
      * Service level strategy rules that are taken into consideration during task placement. List from top to bottom in order of precedence. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. The maximum number of `ordered_placement_strategy` blocks is `5`. See below.
      */
diff --git a/sdk/python/pulumi_awsx/ecs/ec2_service.py b/sdk/python/pulumi_awsx/ecs/ec2_service.py
index 5c85884a..01bd1ae7 100644
--- a/sdk/python/pulumi_awsx/ecs/ec2_service.py
+++ b/sdk/python/pulumi_awsx/ecs/ec2_service.py
@@ -16,7 +16,6 @@ __all__ = ['EC2ServiceArgs', 'EC2Service']
 @pulumi.input_type
 class EC2ServiceArgs:
     def __init__(__self__, *,
-                 network_configuration: pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs'],
                  cluster: Optional[pulumi.Input[str]] = None,
                  continue_before_steady_state: Optional[pulumi.Input[bool]] = None,
                  deployment_circuit_breaker: Optional[pulumi.Input['pulumi_aws.ecs.ServiceDeploymentCircuitBreakerArgs']] = None,
@@ -31,6 +30,7 @@ class EC2ServiceArgs:
                  iam_role: Optional[pulumi.Input[str]] = None,
                  load_balancers: Optional[pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServiceLoadBalancerArgs']]]] = None,
                  name: Optional[pulumi.Input[str]] = None,
+                 network_configuration: Optional[pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs']] = None,
                  ordered_placement_strategies: Optional[pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServiceOrderedPlacementStrategyArgs']]]] = None,
                  placement_constraints: Optional[pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServicePlacementConstraintArgs']]]] = None,
                  platform_version: Optional[pulumi.Input[str]] = None,
@@ -42,7 +42,6 @@ class EC2ServiceArgs:
                  task_definition_args: Optional['EC2ServiceTaskDefinitionArgs'] = None):
         """
         The set of arguments for constructing a EC2Service resource.
-        :param pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs'] network_configuration: Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
         :param pulumi.Input[str] cluster: ARN of an ECS cluster.
         :param pulumi.Input[bool] continue_before_steady_state: If `true`, this provider will not wait for the service to reach a steady state (like [`aws ecs wait services-stable`](https://docs.aws.amazon.com/cli/latest/reference/ecs/wait/services-stable.html)) before continuing. Default `false`.
         :param pulumi.Input['pulumi_aws.ecs.ServiceDeploymentCircuitBreakerArgs'] deployment_circuit_breaker: Configuration block for deployment circuit breaker. See below.
@@ -57,6 +56,7 @@ class EC2ServiceArgs:
         :param pulumi.Input[str] iam_role: ARN of the IAM role that allows Amazon ECS to make calls to your load balancer on your behalf. This parameter is required if you are using a load balancer with your service, but only if your task definition does not use the `awsvpc` network mode. If using `awsvpc` network mode, do not specify this role. If your account has already created the Amazon ECS service-linked role, that role is used by default for your service unless you specify a role here.
         :param pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServiceLoadBalancerArgs']]] load_balancers: Configuration block for load balancers. See below.
         :param pulumi.Input[str] name: Name of the service (up to 255 letters, numbers, hyphens, and underscores)
+        :param pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs'] network_configuration: Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
         :param pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServiceOrderedPlacementStrategyArgs']]] ordered_placement_strategies: Service level strategy rules that are taken into consideration during task placement. List from top to bottom in order of precedence. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. The maximum number of `ordered_placement_strategy` blocks is `5`. See below.
         :param pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServicePlacementConstraintArgs']]] placement_constraints: Rules that are taken into consideration during task placement. Updates to this configuration will take effect next task deployment unless `force_new_deployment` is enabled. Maximum number of `placement_constraints` is `10`. See below.
         :param pulumi.Input[str] platform_version: Platform version on which to run your service. Only applicable for `launch_type` set to `FARGATE`. Defaults to `LATEST`. More information about Fargate platform versions can be found in the [AWS ECS User Guide](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html).
@@ -67,7 +67,6 @@ class EC2ServiceArgs:
         :param pulumi.Input[str] task_definition: Family and revision (`family:revision`) or full ARN of the task definition that you want to run in your service. Either [taskDefinition] or [taskDefinitionArgs] must be provided.
         :param 'EC2ServiceTaskDefinitionArgs' task_definition_args: The args of task definition that you want to run in your service. Either [taskDefinition] or [taskDefinitionArgs] must be provided.
         """
-        pulumi.set(__self__, "network_configuration", network_configuration)
         if cluster is not None:
             pulumi.set(__self__, "cluster", cluster)
         if continue_before_steady_state is not None:
@@ -96,6 +95,8 @@ class EC2ServiceArgs:
             pulumi.set(__self__, "load_balancers", load_balancers)
         if name is not None:
             pulumi.set(__self__, "name", name)
+        if network_configuration is not None:
+            pulumi.set(__self__, "network_configuration", network_configuration)
         if ordered_placement_strategies is not None:
             pulumi.set(__self__, "ordered_placement_strategies", ordered_placement_strategies)
         if placement_constraints is not None:
@@ -115,18 +116,6 @@ class EC2ServiceArgs:
         if task_definition_args is not None:
             pulumi.set(__self__, "task_definition_args", task_definition_args)
 
-    @property
-    @pulumi.getter(name="networkConfiguration")
-    def network_configuration(self) -> pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs']:
-        """
-        Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
-        """
-        return pulumi.get(self, "network_configuration")
-
-    @network_configuration.setter
-    def network_configuration(self, value: pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs']):
-        pulumi.set(self, "network_configuration", value)
-
     @property
     @pulumi.getter
     def cluster(self) -> Optional[pulumi.Input[str]]:
@@ -295,6 +284,18 @@ class EC2ServiceArgs:
     def name(self, value: Optional[pulumi.Input[str]]):
         pulumi.set(self, "name", value)
 
+    @property
+    @pulumi.getter(name="networkConfiguration")
+    def network_configuration(self) -> Optional[pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs']]:
+        """
+        Network configuration for the service. This parameter is required for task definitions that use the `awsvpc` network mode to receive their own Elastic Network Interface, and it is not supported for other network modes. See below.
+        """
+        return pulumi.get(self, "network_configuration")
+
+    @network_configuration.setter
+    def network_configuration(self, value: Optional[pulumi.Input['pulumi_aws.ecs.ServiceNetworkConfigurationArgs']]):
+        pulumi.set(self, "network_configuration", value)
+
     @property
     @pulumi.getter(name="orderedPlacementStrategies")
     def ordered_placement_strategies(self) -> Optional[pulumi.Input[Sequence[pulumi.Input['pulumi_aws.ecs.ServiceOrderedPlacementStrategyArgs']]]]:
@@ -469,7 +470,7 @@ class EC2Service(pulumi.ComponentResource):
     @overload
     def __init__(__self__,
                  resource_name: str,
-                 args: EC2ServiceArgs,
+                 args: Optional[EC2ServiceArgs] = None,
                  opts: Optional[pulumi.ResourceOptions] = None):
         """
         Create an ECS Service resource for EC2 with the given unique name, arguments, and options.
@@ -542,8 +543,6 @@ class EC2Service(pulumi.ComponentResource):
             __props__.__dict__["iam_role"] = iam_role
             __props__.__dict__["load_balancers"] = load_balancers
             __props__.__dict__["name"] = name
-            if network_configuration is None and not opts.urn:
-                raise TypeError("Missing required property 'network_configuration'")
             __props__.__dict__["network_configuration"] = network_configuration
             __props__.__dict__["ordered_placement_strategies"] = ordered_placement_strategies
             __props__.__dict__["placement_constraints"] = placement_constraints


Test patch:
diff --git a/awsx/ecs/ec2TaskDefinition.test.ts b/awsx/ecs/ec2TaskDefinition.test.ts
new file mode 100644
index 00000000..8fd36472
--- /dev/null
+++ b/awsx/ecs/ec2TaskDefinition.test.ts
@@ -0,0 +1,61 @@
+// Copyright 2016-2022, Pulumi Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+import * as pulumi from "@pulumi/pulumi";
+
+import { EC2TaskDefinition } from "./ec2TaskDefinition";
+
+function promiseOf<T>(output: pulumi.Output<T>): Promise<T> {
+  return new Promise((resolve) => output.apply(resolve));
+}
+
+describe("validateNetworkMode", () => {
+  beforeAll(() => {
+    // Put Pulumi in unit-test mode, mocking all calls to cloud-provider APIs.
+    pulumi.runtime.setMocks({
+      // Mock calls to create new resources and return a canned response.
+      newResource: (args: pulumi.runtime.MockResourceArgs): { id: string; state: any } => {
+        // Here, we're returning a same-shaped object for all resource types.
+        // We could, however, use the arguments passed into this function to
+        // customize the mocked-out properties of a particular resource.
+        // See the unit-testing docs for details:
+        // https://www.pulumi.com/docs/guides/testing/unit
+        return {
+          id: `${args.name}-id`,
+          state: args.inputs,
+        };
+      },
+
+      // Mock function calls and return whatever input properties were provided.
+      call: (args: pulumi.runtime.MockCallArgs) => {
+        return args.inputs;
+      },
+    });
+  });
+
+  it("the default network mode should be awsvpc", async () => {
+    const taskDefinition = new EC2TaskDefinition("default", {
+      container: {},
+    });
+    const networkMode = await promiseOf(taskDefinition.taskDefinition.networkMode);
+    expect(networkMode).toBe("awsvpc");
+  });
+  it("when network mode is set, use it", async () => {
+    const taskDefinition = new EC2TaskDefinition("default", {
+      container: {},
+      networkMode: "bridge",
+    });
+    const networkMode = await promiseOf(taskDefinition.taskDefinition.networkMode);
+    expect(networkMode).toBe("bridge");
+  });
+});