You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2016/06/02 22:36:19 UTC

[2/2] jclouds-labs git commit: JCLOUDS-664 Azurecompute-arm DeploymentApi OSImageApi VMSizeApi

JCLOUDS-664 Azurecompute-arm DeploymentApi OSImageApi VMSizeApi


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/fca7addf
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/fca7addf
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/fca7addf

Branch: refs/heads/master
Commit: fca7addf03239f59706c765d6011df41414ae676
Parents: 17a12fc
Author: Rita Zhang <ri...@gmail.com>
Authored: Mon May 16 18:55:01 2016 -0700
Committer: Ignasi Barrera <na...@apache.org>
Committed: Fri Jun 3 00:25:57 2016 +0200

----------------------------------------------------------------------
 .../azurecompute/arm/AzureComputeApi.java       |  32 ++
 .../arm/config/AzureComputeHttpApiModule.java   |   4 +
 .../arm/config/AzureComputeProperties.java      |   2 +
 .../azurecompute/arm/domain/ComputeNode.java    |  31 ++
 .../azurecompute/arm/domain/Deployment.java     | 254 +++++++++++++
 .../azurecompute/arm/domain/DeploymentBody.java |  42 +++
 .../arm/domain/DeploymentProperties.java        |  31 ++
 .../arm/domain/DeploymentTemplate.java          | 105 ++++++
 .../jclouds/azurecompute/arm/domain/Offer.java  |  51 +++
 .../azurecompute/arm/domain/Publisher.java      |  52 +++
 .../arm/domain/ResourceDefinition.java          | 103 +++++
 .../jclouds/azurecompute/arm/domain/SKU.java    |  51 +++
 .../azurecompute/arm/domain/StorageService.java |  48 ++-
 .../azurecompute/arm/domain/VMDeployment.java   |  29 ++
 .../jclouds/azurecompute/arm/domain/VMSize.java |  67 ++++
 .../azurecompute/arm/domain/Version.java        |  49 +++
 .../arm/features/DeploymentApi.java             | 109 ++++++
 .../arm/features/NetworkInterfaceCardApi.java   |   8 +-
 .../azurecompute/arm/features/OSImageApi.java   |  84 +++++
 .../arm/features/StorageAccountApi.java         |   4 +-
 .../azurecompute/arm/features/VMSizeApi.java    |  45 +++
 .../arm/functions/ParseJobStatus.java           |   3 +
 .../arm/util/DeploymentTemplateBuilder.java     | 375 +++++++++++++++++++
 .../arm/features/DeploymentApiLiveTest.java     | 226 +++++++++++
 .../arm/features/DeploymentApiMockTest.java     | 154 ++++++++
 .../features/DeploymentTemplateBuilderTest.java | 224 +++++++++++
 .../arm/features/JobApiMockTest.java            |  13 +-
 .../NetworkInterfaceCardApiLiveTest.java        |  31 +-
 .../NetworkInterfaceCardApiMockTest.java        |  11 +-
 .../arm/features/OSImageApiLiveTest.java        |  69 ++++
 .../arm/features/OSImageApiMockTest.java        | 123 ++++++
 .../arm/features/ResourceGroupApiLiveTest.java  |   7 +-
 .../arm/features/StorageAccountApiLiveTest.java |   4 +-
 .../TemplateToDeploymentTemplateLiveTest.java   | 186 +++++++++
 .../arm/features/VMSizeApiLiveTest.java         |  40 ++
 .../arm/features/VMSizeApiMockTest.java         |  57 +++
 .../arm/features/VirtualMachineApiLiveTest.java |  19 +-
 .../arm/functions/URIParserTest.java            |   4 +-
 .../internal/BaseAzureComputeApiLiveTest.java   |  23 +-
 .../resources/createdeploymentaccepted.json     |  33 ++
 .../resources/createdeploymentsucceeded.json    |  36 ++
 .../src/test/resources/listdeployments.json     |  99 +++++
 azurecompute-arm/src/test/resources/offers.json |   7 +
 .../src/test/resources/publishers.json          |  12 +
 azurecompute-arm/src/test/resources/skus.json   |  12 +
 .../src/test/resources/versions.json            |  12 +
 .../src/test/resources/vmsizes.json             |  28 ++
 47 files changed, 2970 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
index f8ac6e9..4e10089 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
@@ -16,17 +16,22 @@
  */
 package org.jclouds.azurecompute.arm;
 
+import org.jclouds.azurecompute.arm.features.DeploymentApi;
 import org.jclouds.azurecompute.arm.features.JobApi;
 import org.jclouds.azurecompute.arm.features.LocationApi;
 import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
+import org.jclouds.azurecompute.arm.features.OSImageApi;
 import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
 import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
 import org.jclouds.azurecompute.arm.features.StorageAccountApi;
 import org.jclouds.azurecompute.arm.features.SubnetApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
+import org.jclouds.azurecompute.arm.features.VMSizeApi;
+import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
 import org.jclouds.rest.annotations.Delegate;
 
+import com.google.inject.Provides;
 import javax.ws.rs.PathParam;
 import java.io.Closeable;
 
@@ -108,4 +113,31 @@ public interface AzureComputeApi extends Closeable {
    @Delegate
    VirtualMachineApi getVirtualMachineApi(@PathParam("resourceGroup") String resourceGroup);
 
+   /**
+    * This Azure Resource Manager API lists all available virtual machine sizes for a subscription in a given region
+    *
+    * @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt269440.aspx">docs</a>
+    */
+   @Delegate
+   VMSizeApi getVMSizeApi(@PathParam("location") String location);
+
+   /**
+    * The Azure Resource Manager API gets all the OS images in your subscription.
+    *
+    * @see <a href="http://msdn.microsoft.com/en-us/library/jj157175">docs</a>
+    */
+   @Delegate
+   OSImageApi getOSImageApi(@PathParam("location") String location);
+
+   /**
+    * The Deployment API allows for the management of Azure Resource Manager resources through the use of templates.
+    *
+    * @see <a href="https://msdn.microsoft.com/en-us/library/azure/dn790549.aspx">docs</a>
+    */
+   @Delegate
+   DeploymentApi getDeploymentApi(@PathParam("resourcegroup") String resourceGroup);
+
+   @Provides
+   DeploymentTemplateBuilder.Factory deploymentTemplateFactory();
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
index eb6a6d6..30cbc1e 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
@@ -17,6 +17,8 @@
 package org.jclouds.azurecompute.arm.config;
 import org.jclouds.azurecompute.arm.AzureComputeApi;
 import org.jclouds.azurecompute.arm.handlers.AzureComputeErrorHandler;
+import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
+
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.annotation.ClientError;
 import org.jclouds.http.annotation.Redirection;
@@ -28,6 +30,7 @@ import org.jclouds.rest.ConfiguresHttpApi;
 import org.jclouds.rest.config.HttpApiModule;
 import org.jclouds.oauth.v2.config.OAuthScopes;
 
+import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.Scopes;
 
 @ConfiguresHttpApi
@@ -51,6 +54,7 @@ public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
    @Override
    protected void configure() {
       install(new AzureComputeParserModule());
+      install(new FactoryModuleBuilder().build(DeploymentTemplateBuilder.Factory.class));
       super.configure();
       bind(OAuthScopes.class).toInstance(OAuthScopes.NoScopes.create());
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
index e16b5da..48188c4 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
@@ -31,4 +31,6 @@ public class AzureComputeProperties {
 
    public static final String TCP_RULE_REGEXP = "jclouds.azurecompute.arm.tcp.rule.regexp";
 
+   public static final String STORAGE_API_VERSION = "2015-06-15";
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ComputeNode.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ComputeNode.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ComputeNode.java
new file mode 100644
index 0000000..516bbf6
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ComputeNode.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
+
+public class ComputeNode {
+   public enum Status {
+      GOOD,
+      BAD,
+      UNRECOGNIZED;
+
+      public static Status fromValue(final String text) {
+         return (Status) GetEnumValue.fromValueOrDefault(text, Status.UNRECOGNIZED);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Deployment.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Deployment.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Deployment.java
new file mode 100644
index 0000000..2fc85bc
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Deployment.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import static com.google.common.collect.ImmutableList.copyOf;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
+import org.jclouds.domain.JsonBall;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class Deployment {
+
+   public enum ProvisioningState {
+      ACCEPTED,
+      READY,
+      CANCELED,
+      FAILED,
+      DELETED,
+      SUCCEEDED,
+      RUNNING,
+      UNRECOGNIZED;
+
+      public static ProvisioningState fromValue(final String text) {
+         return (ProvisioningState) GetEnumValue.fromValueOrDefault(text, ProvisioningState.UNRECOGNIZED);
+      }
+   }
+
+   public enum DeploymentMode {
+      INCREMENTAL,
+      COMPLETE,
+      UNRECOGNIZED;
+
+      public static DeploymentMode fromValue(final String text) {
+         return (DeploymentMode) GetEnumValue.fromValueOrDefault(text, DeploymentMode.UNRECOGNIZED);
+      }
+   }
+
+   @AutoValue
+   public abstract static class TypeValue {
+      public abstract String type();
+
+      public abstract String value();
+
+      @SerializedNames({"type", "value"})
+      public static TypeValue create(final String type, final String value) {
+         return new AutoValue_Deployment_TypeValue(type, value);
+      }
+   }
+
+   @AutoValue
+   public abstract static class ProviderResourceType {
+      @Nullable
+      public abstract String resourceType();
+
+      @Nullable
+      public abstract List<String> locations();
+
+      @Nullable
+      public abstract List<String> apiVersions();
+
+      @Nullable
+      public abstract Map<String, JsonBall> properties();
+
+      @SerializedNames({"resourceType", "locations", "apiVersions", "properties"})
+      public static ProviderResourceType create(final String resourceType,
+                                                final List<String> locations,
+                                                final List<String> apiVersions,
+                                                @Nullable final Map<String, JsonBall> properties) {
+         return new AutoValue_Deployment_ProviderResourceType(resourceType,
+                 locations == null ? null : copyOf(locations),
+                 apiVersions == null ? null : copyOf(apiVersions),
+                 properties == null ? ImmutableMap.<String, JsonBall>builder().build() : ImmutableMap.copyOf(properties));
+      }
+   }
+
+   @AutoValue
+   public abstract static class Provider {
+      @Nullable
+      public abstract String id();
+
+      @Nullable
+      public abstract String namespace();
+
+      @Nullable
+      public abstract String registrationState();
+
+      @Nullable
+      public abstract List<ProviderResourceType> resourceTypes();
+
+      @SerializedNames({"id", "namespace", "registrationState", "resourceTypes"})
+      public static Provider create(final String id,
+                                    final String namespace,
+                                    final String registrationState,
+                                    final List<ProviderResourceType> resourceTypes) {
+         return new AutoValue_Deployment_Provider(id, namespace, registrationState, resourceTypes == null ? null : copyOf(resourceTypes));
+      }
+   }
+
+   @AutoValue
+   public abstract static class Dependency {
+      @Nullable
+      public abstract List<Dependency> dependencies();
+
+      @Nullable
+      public abstract List<Dependency> dependsOn();
+
+      @Nullable
+      public abstract String id();
+
+      @Nullable
+      public abstract String resourceType();
+
+      @Nullable
+      public abstract String resourceName();
+
+      @SerializedNames({"dependencies", "dependsOn", "id", "resourceType", "resourceName"})
+      public static Dependency create(final List<Dependency> dependencies,
+                                      final List<Dependency> dependsOn,
+                                      final String id,
+                                      final String resourceType,
+                                      final String resourceName) {
+         return new AutoValue_Deployment_Dependency(dependencies == null ? null : copyOf(dependencies),
+               dependsOn == null ? null : copyOf(dependsOn), id, resourceType, resourceName);
+      }
+   }
+
+   @AutoValue
+   public abstract static class ContentLink {
+      public abstract String uri();
+
+      @Nullable
+      public abstract String contentVersion();
+
+      @SerializedNames({"uri", "contentVersion"})
+      public static ContentLink create(final String uri, final String contentVersion) {
+         return new AutoValue_Deployment_ContentLink(uri, contentVersion);
+      }
+   }
+
+   @AutoValue
+   public abstract static class DeploymentProperties {
+      @Nullable
+      public abstract String provisioningState();
+
+      @Nullable
+      public abstract String correlationId();
+
+      @Nullable
+      public abstract String timestamp();
+
+      @Nullable
+      public abstract Map<String, JsonBall> outputs();
+
+      @Nullable
+      public abstract List<Provider> providers();
+
+      @Nullable
+      public abstract List<Dependency> dependencies();
+
+      @Nullable
+      public abstract Map<String, JsonBall> template();
+
+      @Nullable
+      public abstract ContentLink templateLink();
+
+      @Nullable
+      public abstract Map<String, JsonBall> parameters();
+
+      @Nullable
+      public abstract ContentLink parametersLink();
+
+      public abstract String mode();
+
+      // The entries below seem to be dynamic/not documented in the specification
+      @Nullable
+      public abstract String duration();
+
+      @Nullable
+      public abstract List<Map<String, String>> outputResources();
+
+      @SerializedNames({"provisioningState", "correlationId", "timestamp", "outputs", "providers", "dependencies", "template", "templateLink", "parameters", "parametersLink", "mode", "duration", "outputResources"})
+      public static DeploymentProperties create(final String provisioningState,
+                                                final String correlationId,
+                                                final String timestamp,
+                                                @Nullable final Map<String, JsonBall> outputs,
+                                                final List<Provider> providers,
+                                                final List<Dependency> dependencies,
+                                                final Map<String, JsonBall> template,
+                                                final ContentLink templateLink,
+                                                final Map<String, JsonBall> parameters,
+                                                final ContentLink parametersLink,
+                                                final String mode,
+                                                final String duration,
+                                                final List<Map<String, String>> outputResources) {
+         return new AutoValue_Deployment_DeploymentProperties(provisioningState,
+                                                              correlationId,
+                                                              timestamp,
+                                                              outputs == null ? ImmutableMap.<String, JsonBall>builder().build() : ImmutableMap.copyOf(outputs),
+                                                              providers == null ? null : copyOf(providers),
+                                                              dependencies == null ? null : copyOf(dependencies),
+                                                              template == null ? ImmutableMap.<String, JsonBall>builder().build() : ImmutableMap.copyOf(template),
+                                                              templateLink,
+                                                              parameters == null ? ImmutableMap.<String, JsonBall>builder().build() : ImmutableMap.copyOf(parameters),
+                                                              parametersLink,
+                                                              mode,
+                                                              duration,
+                                                              outputResources == null ? null : copyOf(outputResources));
+      }
+   }
+
+   /**
+    * The ID associated with the template deployment.
+    */
+   @Nullable
+   public abstract String id();
+
+   /**
+    * The name associated with the template deployment.
+    */
+   public abstract String name();
+
+   /**
+    * Properties of the deployment.
+    */
+   @Nullable
+   public abstract DeploymentProperties properties();
+
+   @SerializedNames({"id", "name", "properties"})
+   public static Deployment create(final String id, final String name, final DeploymentProperties properties) {
+      return new AutoValue_Deployment(id, name, properties);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentBody.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentBody.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentBody.java
new file mode 100644
index 0000000..0f91360
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentBody.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.azurecompute.arm.domain.DeploymentTemplate.Parameters;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class DeploymentBody {
+
+   @Nullable
+   public abstract DeploymentTemplate template();
+
+   @Nullable
+   public abstract String mode();
+
+   @Nullable
+   public abstract Parameters parameters();
+
+   @SerializedNames({"template", "mode", "parameters"})
+   public static DeploymentBody create(final DeploymentTemplate template,
+                                       final String mode,
+                                       final Parameters parameters) {
+      return new AutoValue_DeploymentBody(template, mode, parameters);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentProperties.java
new file mode 100644
index 0000000..94b53c5
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentProperties.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class DeploymentProperties {
+
+   public abstract DeploymentBody properties();
+
+   @SerializedNames({"properties"})
+   public static DeploymentProperties create(final DeploymentBody properties) {
+      return new AutoValue_DeploymentProperties(properties);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
new file mode 100644
index 0000000..848000d
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.javax.annotation.Nullable;
+
+import java.util.List;
+import java.util.Map;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class DeploymentTemplate {
+
+   //Empty placeholders as we want to generate the empty JSON object
+   @AutoValue
+   public abstract static class Parameters {
+      public static Parameters create() {
+         return new AutoValue_DeploymentTemplate_Parameters();
+      }
+   }
+
+   public abstract String schema();
+
+   public abstract String contentVersion();
+
+   public abstract Parameters parameters();
+
+   public abstract Map<String, String> variables();
+
+   public abstract List<ResourceDefinition> resources();
+
+   @Nullable
+   public abstract List<?> outputs();
+
+   @SerializedNames({"$schema", "contentVersion", "parameters", "variables", "resources" , "outputs"})
+   public static DeploymentTemplate create(final String schema,
+                                           final String contentVersion,
+                                           final Parameters parameters,
+                                           final Map<String, String> variables,
+                                           final List<ResourceDefinition> resources,
+                                           final List<?> outputs) {
+
+      DeploymentTemplate.Builder builder = DeploymentTemplate.builder()
+              .schema(schema)
+              .contentVersion(contentVersion)
+              .parameters(parameters);
+
+      if (variables != null)
+         builder.variables(variables);
+
+      if (resources != null)
+         builder.resources(resources);
+
+      builder.outputs(outputs == null ? null : ImmutableList.copyOf(outputs));
+
+      return builder.build();
+   }
+
+   public static Builder builder() {
+      return new AutoValue_DeploymentTemplate.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder schema(String schema);
+
+      public abstract Builder contentVersion(String type);
+
+      public abstract Builder parameters(Parameters parameters);
+
+      public abstract Builder variables(Map<String, String> variables);
+
+      public abstract Builder resources(List<ResourceDefinition> resources);
+
+      public abstract Builder outputs(List<?> outputs);
+
+      abstract Map<String, String> variables();
+      abstract List<ResourceDefinition> resources();
+
+      abstract DeploymentTemplate autoBuild();
+
+      public DeploymentTemplate build() {
+         variables(variables() != null ? ImmutableMap.copyOf(variables()) : null);
+         resources(resources() != null ? ImmutableList.copyOf(resources()) : null);
+         return autoBuild();
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Offer.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Offer.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Offer.java
new file mode 100644
index 0000000..d44c8f8
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Offer.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+/**
+ * Offer
+ */
+@AutoValue
+public abstract class Offer {
+   /**
+    * The location of the Offer
+    */
+   @Nullable
+   public abstract String location();
+
+   /**
+    * The name of the Offer
+    */
+   @Nullable
+   public abstract String name();
+
+   /**
+    * The id of the Offer
+    */
+   @Nullable
+   public abstract String id();
+
+   @SerializedNames({"location", "name", "id"})
+   public static Offer create(final String location, final String name, final String id) {
+
+      return new AutoValue_Offer(location, name, id);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Publisher.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Publisher.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Publisher.java
new file mode 100644
index 0000000..4f5c53f
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Publisher.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+/**
+ * Publisher
+ */
+@AutoValue
+public abstract class Publisher {
+
+   /**
+    * The location of the publisher
+    */
+   @Nullable
+   public abstract String location();
+
+   /**
+    * The name of the publisher
+    */
+   @Nullable
+   public abstract String name();
+
+   /**
+    * The id of the publisher
+    */
+   @Nullable
+   public abstract String id();
+
+   @SerializedNames({"location", "name", "id"})
+   public static Publisher create(final String location, final String name, final String id) {
+
+      return new AutoValue_Publisher(location, name, id);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceDefinition.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceDefinition.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceDefinition.java
new file mode 100644
index 0000000..7c68e80
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ResourceDefinition.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+import java.util.List;
+import java.util.Map;
+
+@AutoValue
+public abstract class ResourceDefinition {
+
+    public abstract String name();
+
+    public abstract String type();
+
+    public abstract String location();
+
+    public abstract String apiVersion();
+
+    @Nullable
+    public abstract List<String> dependsOn();
+
+    @Nullable
+    public abstract Map<String, String> tags();
+
+    @Nullable
+    public abstract Object properties();
+
+    @SerializedNames({"name", "type", "location", "apiVersion", "dependsOn", "tags", "properties"})
+    public static ResourceDefinition create(final String name,
+                                            final String type,
+                                            final String location,
+                                            final String apiVersion,
+                                            final List<String> dependsOn,
+                                            final Map<String, String> tags,
+                                            final Object properties) {
+        ResourceDefinition.Builder builder = ResourceDefinition.builder()
+                .name(name)
+                .type(type)
+                .location(location)
+                .apiVersion(apiVersion)
+                .properties(properties);
+
+        builder.dependsOn(dependsOn == null ? null : ImmutableList.copyOf(dependsOn));
+
+        builder.tags(tags == null ? null : ImmutableMap.copyOf(tags));
+
+        return  builder.build();
+    }
+
+    public static Builder builder() {
+        return new AutoValue_ResourceDefinition.Builder();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+        public abstract Builder name(String name);
+
+        public abstract Builder type(String type);
+
+        public abstract Builder location(String location);
+
+        public abstract Builder apiVersion(String apiVersion);
+
+        public abstract Builder dependsOn(List<String> dependencies);
+
+        public abstract Builder tags(Map<String, String> tags);
+
+        public abstract Builder properties(Object properties);
+
+        abstract List<String>  dependsOn();
+        abstract Map<String, String>  tags();
+
+        abstract ResourceDefinition autoBuild();
+
+        public ResourceDefinition build() {
+            dependsOn(dependsOn() != null ? ImmutableList.copyOf(dependsOn()) : null);
+            tags(tags() != null ? ImmutableMap.copyOf(tags()) : null);
+            return autoBuild();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/SKU.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/SKU.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/SKU.java
new file mode 100644
index 0000000..4c414e5
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/SKU.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+/**
+ * SKU
+ */
+@AutoValue
+public abstract class SKU {
+   /**
+    * The location of the SKU
+    */
+   @Nullable
+   public abstract String location();
+
+   /**
+    * The name of the SKU
+    */
+   @Nullable
+   public abstract String name();
+
+   /**
+    * The id of the SKU
+    */
+   @Nullable
+   public abstract String id();
+
+   @SerializedNames({"location", "name", "id"})
+   public static SKU create(final String location, final String name, final String id) {
+
+      return new AutoValue_SKU(location, name, id);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageService.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageService.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageService.java
index a151aec..a97117f 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageService.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageService.java
@@ -19,7 +19,6 @@ package org.jclouds.azurecompute.arm.domain;
 import com.google.auto.value.AutoValue;
 import java.util.Date;
 import java.util.Map;
-
 import com.google.common.collect.ImmutableMap;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
@@ -83,11 +82,13 @@ public abstract class StorageService {
        /**
         * Specifies the time that the storage account was created.
         */
+       @Nullable
        public abstract Date creationTime();
 
        /**
         * Specifies the endpoints of the storage account.
         */
+       @Nullable
        public abstract Map<String, String> primaryEndpoints();
 
        /**
@@ -105,6 +106,7 @@ public abstract class StorageService {
        /**
         * Specifies the secondary endpoints of the storage account.
         */
+       @Nullable
        public abstract Map<String, String> secondaryEndpoints();
 
       /**
@@ -133,9 +135,47 @@ public abstract class StorageService {
               final Map<String, String> secondaryEndpoints, final String secondaryLocation,
               final RegionStatus statusOfPrimary, final RegionStatus statusOfSecondary) {
 
-         return new AutoValue_StorageService_StorageServiceProperties(accountType, creationTime,
-                 primaryEndpoints == null ? ImmutableMap.<String, String>builder().build() : ImmutableMap.copyOf(primaryEndpoints), primaryLocation, provisioningState,
-                 secondaryEndpoints == null ? ImmutableMap.<String, String>builder().build() : ImmutableMap.copyOf(secondaryEndpoints), secondaryLocation, statusOfPrimary, statusOfSecondary);
+         StorageServiceProperties.Builder builder = StorageServiceProperties.builder()
+                 .accountType(accountType)
+                 .creationTime(creationTime)
+                 .primaryLocation(primaryLocation)
+                 .provisioningState(provisioningState)
+                 .secondaryLocation(secondaryLocation)
+                 .statusOfPrimary(statusOfPrimary)
+                 .statusOfSecondary(statusOfSecondary);
+
+
+         builder.primaryEndpoints(primaryEndpoints != null ? ImmutableMap.copyOf(primaryEndpoints) : null);
+         builder.secondaryEndpoints(secondaryEndpoints != null ? ImmutableMap.copyOf(secondaryEndpoints) : null);
+
+         return  builder.build();
+      }
+      public static Builder builder() {
+         return new AutoValue_StorageService_StorageServiceProperties.Builder();
+      }
+
+      @AutoValue.Builder
+      public abstract static class Builder {
+         public abstract Builder accountType(AccountType accountType);
+         public abstract Builder creationTime(Date creationTime);
+         public abstract Builder primaryEndpoints(Map<String, String> primaryEndpoints);
+         public abstract Builder primaryLocation(String primaryLocation);
+         public abstract Builder provisioningState(Status provisioningState);
+         public abstract Builder secondaryEndpoints(Map<String, String> secondaryEndpoints);
+         public abstract Builder secondaryLocation(String secondaryLocation);
+         public abstract Builder statusOfPrimary(RegionStatus statusOfPrimary);
+         public abstract Builder statusOfSecondary(RegionStatus statusOfSecondary);
+
+         abstract Map<String, String>  primaryEndpoints();
+         abstract Map<String, String>  secondaryEndpoints();
+
+         abstract StorageServiceProperties autoBuild();
+
+         public StorageServiceProperties build() {
+            primaryEndpoints(primaryEndpoints() != null ? ImmutableMap.copyOf(primaryEndpoints()) : null);
+            secondaryEndpoints(secondaryEndpoints() != null ? ImmutableMap.copyOf(secondaryEndpoints()) : null);
+            return autoBuild();
+         }
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
new file mode 100644
index 0000000..2504409
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+
+import java.util.List;
+
+public class VMDeployment {
+
+   public Deployment deployment;
+
+   public List<PublicIPAddress> ipAddressList;
+
+   public VirtualMachineInstance vm;
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMSize.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMSize.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMSize.java
new file mode 100644
index 0000000..6794735
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMSize.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
+
+/**
+ * A VM Size that is available in a region for a given subscription.
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt269440.aspx" >api</a>
+ */
+@AutoValue
+public abstract class VMSize {
+
+   /**
+    * The name of the VM size.
+    */
+   public abstract String name();
+
+   /**
+    * The number of cores that are available in the VM size.
+    */
+   public abstract Integer numberOfCores();
+
+   /**
+    * Specifies the size in MB of the OS Disk.
+    */
+   public abstract Integer osDiskSizeInMB();
+
+   /**
+    * The size of the resource disk.
+    */
+   public abstract Integer resourceDiskSizeInMB();
+
+   /**
+    * Specifies the available RAM in MB.
+    */
+   public abstract Integer memoryInMB();
+
+   /**
+    * Specifies the maximum number of data disks that can be attached to the VM size.
+    */
+   public abstract Integer maxDataDiskCount();
+
+   @SerializedNames({ "name", "numberOfCores", "osDiskSizeInMB", "resourceDiskSizeInMB", "memoryInMB", "maxDataDiskCount"})
+   public static VMSize create(final String name, final Integer numberOfCores, final Integer osDiskSizeInMB,
+           final Integer resourceDiskSizeInMB, final Integer memoryInMB, final Integer maxDataDiskCount) {
+
+      return new AutoValue_VMSize(name, numberOfCores, osDiskSizeInMB, resourceDiskSizeInMB, memoryInMB, maxDataDiskCount);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Version.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Version.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Version.java
new file mode 100644
index 0000000..63d7e11
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Version.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
+
+/**
+ * Version
+ */
+@AutoValue
+public abstract class Version {
+
+   /**
+    * The location of the Version
+    */
+   public abstract String location();
+
+   /**
+    * The name of the Version
+    */
+   public abstract String name();
+
+   /**
+    * The id of the Version
+    */
+   public abstract String id();
+
+   @SerializedNames({"location", "name", "id"})
+   public static Version create(final String location, final String name, final String id) {
+
+      return new AutoValue_Version(location, name, id);
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
new file mode 100644
index 0000000..550f8ea
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import javax.inject.Named;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+
+import org.jclouds.azurecompute.arm.domain.Deployment;
+import org.jclouds.azurecompute.arm.functions.URIParser;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Payload;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SelectJson;
+
+import java.net.URI;
+import java.util.List;
+
+/**
+ * - create deployment
+ * - delete deployment
+ * - get information about deployment
+ */
+@Path("/resourcegroups/{resourcegroup}/providers/microsoft.resources/deployments")
+@QueryParams(keys = "api-version", values = "2016-02-01")
+@RequestFilters(OAuthFilter.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface DeploymentApi {
+
+   /**
+    * The Create Template Deployment operation starts the process of an ARM Template deployment.
+    * It then returns a Deployment object.
+    */
+   @Named("deployment:create")
+   @Path("/{deploymentname}")
+   @Payload("{properties}")
+   @PUT
+   @Produces(MediaType.APPLICATION_JSON)
+   Deployment create(@PathParam("deploymentname") String deploymentname,
+                               @PayloadParam("properties") String properties);
+
+   /**
+    * Get Deployment Information returns information about the specified deployment.
+    */
+   @Named("deployment:get")
+   @Path("/{deploymentname}")
+   @GET
+   @Fallback(NullOnNotFoundOr404.class)
+   Deployment get(@PathParam("deploymentname") String deploymentname);
+
+   /**
+    * Validate Deployment validates deployment template before deployment
+    */
+   @Named("deployment:validate")
+   @Path("/{deploymentname}/validate")
+   @Payload("{properties}")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   Deployment validate(@PathParam("deploymentname") String deploymentname,
+                                 @PayloadParam("properties") String properties);
+
+   /**
+    * List all deployments in a resource group
+    */
+   @Named("deployment:list")
+   @GET
+   @SelectJson("value")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<Deployment> list();
+
+   /**
+    * The Delete Template Deployment operation starts the process of an ARM Template removal.
+    */
+   @Named("deployment:delete")
+   @DELETE
+   @ResponseParser(URIParser.class)
+   @Path("/{deploymentname}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   URI delete(@PathParam("deploymentname") String deploymentname);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
index c7c665d..2f19996 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
@@ -20,7 +20,7 @@ import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
-import org.jclouds.azurecompute.arm.functions.FalseOn204;
+import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;
@@ -41,6 +41,7 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.core.MediaType;
 import java.util.List;
 import java.util.Map;
+import java.net.URI;
 
 @Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkInterfaces")
 @QueryParams(keys = "api-version", values = "2015-06-15")
@@ -73,6 +74,7 @@ public interface NetworkInterfaceCardApi {
    @Named("networkinterfacecard:delete")
    @Path("/{networkinterfacecardname}")
    @DELETE
-   @ResponseParser(FalseOn204.class)
-   boolean delete(@PathParam("networkinterfacecardname") String networkinterfacecardname);
+   @ResponseParser(URIParser.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   URI delete(@PathParam("networkinterfacecardname") String networkinterfacecardname);
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
new file mode 100644
index 0000000..96dce6b
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import org.jclouds.azurecompute.arm.domain.Offer;
+import org.jclouds.azurecompute.arm.domain.Publisher;
+import org.jclouds.azurecompute.arm.domain.SKU;
+import org.jclouds.azurecompute.arm.domain.Version;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+
+/**
+ * The Azure Resource Management API includes operations for managing the OS images in your subscription.
+ */
+@Path("/providers/Microsoft.Compute/locations/{location}")
+@RequestFilters(OAuthFilter.class)
+@QueryParams(keys = "api-version", values = "2015-06-15")
+@Consumes(APPLICATION_JSON)
+public interface OSImageApi {
+
+   /**
+    * List Publishers in location
+    */
+   @Named("publisher:list")
+   @GET
+   @Path("/publishers")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<Publisher> listPublishers();
+
+   /**
+    * List Offers in publisher
+    */
+   @Named("offer:list")
+   @GET
+   @Path("/publishers/{publisher}/artifacttypes/vmimage/offers")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<Offer> listOffers(@PathParam("publisher") String publisher);
+
+   /**
+    * List SKUs in offer
+    */
+   @Named("sku:list")
+   @GET
+   @Path("/publishers/{publisher}/artifacttypes/vmimage/offers/{offer}/skus")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<SKU> listSKUs(@PathParam("publisher") String publisher, @PathParam("offer") String offer);
+
+   /**
+    * List Versions in SKU
+    */
+   @Named("version:list")
+   @GET
+   @Path("/publishers/{publisher}/artifacttypes/vmimage/offers/{offer}/skus/{sku}/versions")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<Version> listVersions(@PathParam("publisher") String publisher, @PathParam("offer") String offer,
+                          @PathParam("sku") String sku);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
index 8ebfc82..fd75fca 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
@@ -51,6 +51,8 @@ import java.util.List;
 import java.util.Map;
 import java.net.URI;
 
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
+
 /**
  * The Azure Resource Management API includes operations for managing the storage accounts in your subscription.
  *
@@ -58,7 +60,7 @@ import java.net.URI;
  */
 @Path("/")
 @RequestFilters(OAuthFilter.class)
-@QueryParams(keys = "api-version", values = "2015-06-15")
+@QueryParams(keys = "api-version", values = STORAGE_API_VERSION)
 @Consumes(MediaType.APPLICATION_JSON)
 public interface StorageAccountApi {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VMSizeApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VMSizeApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VMSizeApi.java
new file mode 100644
index 0000000..345e08c
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VMSizeApi.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import org.jclouds.azurecompute.arm.domain.VMSize;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+import java.util.List;
+
+@Path("/providers/Microsoft.Compute/locations/{location}/vmSizes")
+@QueryParams(keys = "api-version", values = "2015-06-15")
+@RequestFilters(OAuthFilter.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface VMSizeApi {
+
+   @Named("vmSizes:list")
+   @GET
+   @SelectJson("value")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<VMSize> list();
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/ParseJobStatus.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/ParseJobStatus.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/ParseJobStatus.java
index 5770582..045431c 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/ParseJobStatus.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/ParseJobStatus.java
@@ -30,6 +30,7 @@ public class ParseJobStatus implements Function<HttpResponse, ParseJobStatus.Job
       DONE,
       IN_PROGRESS,
       FAILED,
+      NO_CONTENT,
       UNRECOGNIZED;
 
       public static JobStatus fromValue(final String text) {
@@ -39,6 +40,8 @@ public class ParseJobStatus implements Function<HttpResponse, ParseJobStatus.Job
    public JobStatus apply(final HttpResponse from) {
       if (from.getStatusCode() == 202 ){
          return JobStatus.IN_PROGRESS;
+      } else if (from.getStatusCode() == 204) {
+         return JobStatus.NO_CONTENT;
       } else if (from.getStatusCode() == 200 ){
          return JobStatus.DONE;
       } else {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/fca7addf/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
new file mode 100644
index 0000000..ffa533e
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java
@@ -0,0 +1,375 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.jclouds.azurecompute.arm.util;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.assistedinject.Assisted;
+
+import org.jclouds.azurecompute.arm.domain.DeploymentProperties;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.azurecompute.arm.domain.DataDisk;
+import org.jclouds.azurecompute.arm.domain.DeploymentBody;
+import org.jclouds.azurecompute.arm.domain.DeploymentTemplate;
+import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile;
+import org.jclouds.azurecompute.arm.domain.DnsSettings;
+import org.jclouds.azurecompute.arm.domain.HardwareProfile;
+import org.jclouds.azurecompute.arm.domain.IdReference;
+import org.jclouds.azurecompute.arm.domain.ImageReference;
+import org.jclouds.azurecompute.arm.domain.IpConfiguration;
+import org.jclouds.azurecompute.arm.domain.IpConfigurationProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkProfile;
+import org.jclouds.azurecompute.arm.domain.OSDisk;
+import org.jclouds.azurecompute.arm.domain.OSProfile;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
+import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
+import org.jclouds.azurecompute.arm.domain.StorageProfile;
+import org.jclouds.azurecompute.arm.domain.StorageService;
+import org.jclouds.azurecompute.arm.domain.StorageService.StorageServiceProperties;
+import org.jclouds.azurecompute.arm.domain.Subnet;
+import org.jclouds.azurecompute.arm.domain.Subnet.SubnetProperties;
+import org.jclouds.azurecompute.arm.domain.VHD;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
+import org.jclouds.azurecompute.arm.domain.VirtualNetwork.VirtualNetworkProperties;
+import org.jclouds.azurecompute.arm.domain.VirtualNetwork.AddressSpace;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.json.Json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.inject.Inject;
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
+
+public class DeploymentTemplateBuilder {
+   public interface Factory {
+      DeploymentTemplateBuilder create(@Assisted("group") String group, @Assisted("name") String name, Template template);
+   }
+
+   private final String name;
+   private final String group;
+   private final Template template;
+   private final Json json;
+
+   private TemplateOptions options;
+   private List<ResourceDefinition> resources;
+   private Map<String, String> variables;
+   private String loginUser;
+   private String loginPassword;
+   private String location;
+
+   public static final String DEFAULT_LOGIN_USER = "jclouds";
+   public static final String DEFAULT_LOGIN_PASSWORD = "Password1!";
+   private static final String DEPLOYMENT_MODE = "Incremental";
+   private static final String DEFAULT_DATA_DISK_SIZE = "1023";
+
+   private static final String DEFAULT_vnAddresSpacePrefix = "10.0.0.0/16";
+   private static final String DEFAULT_subnetAddressPrefix = "10.0.0.0/24";
+
+   @Inject
+   DeploymentTemplateBuilder(Json json, @Assisted("group") String group, @Assisted("name") String name, @Assisted Template template) {
+      this.name = name;
+      this.group = group;
+      this.template = template;
+      this.options = template.getOptions().as(TemplateOptions.class);
+      this.variables = new HashMap<String, String>();
+      this.resources = new ArrayList<ResourceDefinition>();
+      this.loginUser = options.getLoginUser() == null ? DEFAULT_LOGIN_USER : options.getLoginUser();
+      this.loginPassword = options.getLoginPassword() == null ? DEFAULT_LOGIN_PASSWORD : options.getLoginPassword();
+      this.location = template.getLocation().getId();
+      this.json = json;
+   }
+
+   public String getLoginUserUsername() {
+      return loginUser;
+   }
+
+   public String getLoginPassword() {
+      return loginPassword;
+   }
+
+   public Template getTemplate() {
+      return template;
+   }
+
+   public DeploymentBody getDeploymentTemplate() {
+
+      addStorageResource();
+      addVirtualNetworkResource();
+      addPublicIpAddress();
+      addNetworkInterfaceCard();
+      addVirtualMachine();
+
+      DeploymentTemplate template = DeploymentTemplate.builder()
+              .schema("https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#")
+              .contentVersion("1.0.0.0")
+              .resources(resources)
+              .variables(variables)
+              .parameters(DeploymentTemplate.Parameters.create())
+              .build();
+
+      DeploymentBody body = DeploymentBody.create(template, DEPLOYMENT_MODE, DeploymentTemplate.Parameters.create());
+
+      return body;
+   }
+
+   public String getDeploymentTemplateJson(DeploymentProperties properties){
+      return json.toJson(properties);
+   }
+
+   private void addStorageResource() {
+      String storageAccountName = name.replaceAll("[^A-Za-z0-9 ]", "") + "storage";
+
+      variables.put("storageAccountName", storageAccountName);
+
+      ResourceDefinition storageAccount = ResourceDefinition.builder()
+              .name("[variables('storageAccountName')]")
+              .type("Microsoft.Storage/storageAccounts")
+              .location(location)
+              .apiVersion(STORAGE_API_VERSION)
+              .properties(
+                      StorageServiceProperties.builder()
+                              .accountType(StorageService.AccountType.Standard_LRS)
+                              .build()
+              )
+              .build();
+
+      resources.add(storageAccount);
+   }
+
+   private void addVirtualNetworkResource() {
+      String virtualNetworkName = group + "virtualnetwork";
+
+      String subnetName = group + "subnet";
+      variables.put("virtualNetworkName", virtualNetworkName);
+      variables.put("virtualNetworkReference", "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]");
+      variables.put("subnetName", subnetName);
+      variables.put("subnetReference", "[concat(variables('virtualNetworkReference'),'/subnets/',variables('subnetName'))]");
+
+      VirtualNetworkProperties properties = VirtualNetworkProperties.builder()
+              .addressSpace(
+                      AddressSpace.create(Arrays.asList(DEFAULT_vnAddresSpacePrefix))
+              )
+              .subnets(
+                      Arrays.asList(
+                              Subnet.create("[variables('subnetName')]", null, null,
+                                      SubnetProperties.builder()
+                                              .addressPrefix(DEFAULT_subnetAddressPrefix).build()
+                              ))
+              )
+              .build();
+
+
+      ResourceDefinition virtualNetwork = ResourceDefinition.builder()
+              .name("[variables('virtualNetworkName')]")
+              .type("Microsoft.Network/virtualNetworks")
+              .location(location)
+              .apiVersion(STORAGE_API_VERSION)
+              .properties(properties)
+              .build();
+
+      resources.add(virtualNetwork);
+   }
+
+   private void addPublicIpAddress() {
+      String publicIPAddressName = name + "publicip";
+      String dnsLabelPrefix = name; //TODO: read from Azure template properties
+
+      PublicIPAddressProperties.Builder properties = PublicIPAddressProperties.builder();
+
+      if (!dnsLabelPrefix.isEmpty()) {
+         properties.dnsSettings(DnsSettings.builder().domainNameLabel(dnsLabelPrefix).build());
+         variables.put("dnsLabelPrefix", dnsLabelPrefix);
+      }
+
+      properties.publicIPAllocationMethod("Dynamic");
+      variables.put("publicIPAddressName", publicIPAddressName);
+      variables.put("publicIPAddressReference", "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]");
+
+      ResourceDefinition publicIpAddress = ResourceDefinition.builder()
+              .name("[variables('publicIPAddressName')]")
+              .type("Microsoft.Network/publicIPAddresses")
+              .location(location)
+              .apiVersion(STORAGE_API_VERSION)
+              .properties(properties.build())
+              .build();
+
+      resources.add(publicIpAddress);
+   }
+
+   private void addNetworkInterfaceCard() {
+
+      List<IpConfiguration> ipConfigurations = new ArrayList<IpConfiguration>();
+
+      String ipConfigurationName = name + "ipconfig";
+      variables.put("ipConfigurationName", ipConfigurationName);
+
+      IpConfiguration ipConfig = IpConfiguration.create(ipConfigurationName, null, null, null,
+              IpConfigurationProperties.builder()
+                      .privateIPAllocationMethod("Dynamic")
+                      .publicIPAddress(IdReference.create("[variables('publicIPAddressReference')]"))
+                      .subnet(IdReference.create("[variables('subnetReference')]"))
+                      .build());
+
+      ipConfigurations.add(ipConfig);
+
+      NetworkInterfaceCardProperties networkInterfaceCardProperties = NetworkInterfaceCardProperties.builder()
+              .ipConfigurations(ipConfigurations)
+              .build();
+
+      String networkInterfaceCardName = name + "nic";
+      variables.put("networkInterfaceCardName", networkInterfaceCardName);
+      variables.put("networkInterfaceCardReference", "[resourceId('Microsoft.Network/networkInterfaces',variables('networkInterfaceCardName'))]");
+
+      ResourceDefinition networkInterfaceCard = ResourceDefinition.builder()
+              .name("[variables('networkInterfaceCardName')]")
+              .type("Microsoft.Network/networkInterfaces")
+              .location(location)
+              .apiVersion(STORAGE_API_VERSION)
+              .dependsOn(Arrays.asList("[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
+                      "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"))
+              .properties(networkInterfaceCardProperties)
+              .build();
+
+      resources.add(networkInterfaceCard);
+   }
+
+   private void addVirtualMachine() {
+
+      //Build OS Profile
+      final String computerName = name + "pc";
+
+      variables.put("loginUser", loginUser);
+      OSProfile.Builder profileBuilder = OSProfile.builder()
+              .adminUsername(loginUser)
+              .computerName(computerName);
+
+      boolean usePublicKey = options.getPublicKey() != null;
+
+      if (usePublicKey) {
+         OSProfile.LinuxConfiguration configuration = OSProfile.LinuxConfiguration.create("true",
+                 OSProfile.LinuxConfiguration.SSH.create(Arrays.asList(
+                         OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create(
+                                 "[concat('/home/',variables('loginUser'),'/.ssh/authorized_keys')]",
+                                 options.getPublicKey())
+                 ))
+         );
+         profileBuilder.linuxConfiguration(configuration);
+      } else {
+         profileBuilder.adminPassword(loginPassword);
+      }
+
+      OSProfile osProfile = profileBuilder.build();
+
+      //Build Image Reference
+      final String imagePublisher = template.getImage().getProviderId();
+      final String imageOffer = template.getImage().getName();
+      final String imageSku = template.getImage().getVersion();
+
+      ImageReference imageReference = ImageReference.builder()
+              .publisher(imagePublisher)
+              .offer(imageOffer)
+              .sku(imageSku)
+              .version("latest")
+              .build();
+
+      //Build OsDisk
+      final String storageAccountContainerName = "vhds";
+      variables.put("storageAccountContainerName", storageAccountContainerName);
+
+      final String osDiskName = name + "osdisk";
+      variables.put("osDiskName", osDiskName);
+
+      OSDisk osDisk = OSDisk.builder()
+              .name("[variables('osDiskName')]")
+              .vhd(
+                      VHD.create("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('storageAccountContainerName'),'/',variables('osDiskName'),'.vhd')]")
+              )
+              .caching("ReadWrite")
+              .createOption("FromImage")
+              .build();
+
+
+      //Create Data Disk(s) and add to list
+      final String dataDiskName = name + "datadisk";
+      variables.put("dataDiskName", dataDiskName);
+
+      List<DataDisk> dataDisks = new ArrayList<DataDisk>();
+      DataDisk dataDisk = DataDisk.builder()
+              .name("[variables('dataDiskName')]")
+              .diskSizeGB(DEFAULT_DATA_DISK_SIZE)
+              .lun(0)
+              .vhd(
+                      VHD.create("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('storageAccountContainerName'),'/',variables('dataDiskName'),'.vhd')]")
+              )
+              .createOption("Empty")
+              .build();
+
+      dataDisks.add(dataDisk);
+
+      //Create Storage Profile
+      StorageProfile storageProfile = StorageProfile.builder()
+              .imageReference(imageReference)
+              .osDisk(osDisk)
+              .dataDisks(dataDisks)
+              .build();
+
+      //Create Network Profile for this VM (links to network interface cards)
+      NetworkProfile networkProfile = NetworkProfile.create(
+              Arrays.asList(
+                      IdReference.create("[variables('networkInterfaceCardReference')]")
+              ));
+
+      //Boot Diagnostics
+      DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(
+              DiagnosticsProfile.BootDiagnostics.builder()
+                      .enabled(true)
+                      .storageUri("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net')]")
+                      .build());
+
+      //Build VirtualMachine properties based on above properties.
+      final String vmSize = template.getHardware().getId();
+      HardwareProfile hw = HardwareProfile.create(vmSize);
+
+      VirtualMachineProperties properties = VirtualMachineProperties.builder()
+              .hardwareProfile(hw)
+              .osProfile(osProfile)
+              .storageProfile(storageProfile)
+              .networkProfile(networkProfile)
+              .diagnosticsProfile(diagnosticsProfile)
+              .build();
+
+      variables.put("virtualMachineName", name);
+      ResourceDefinition virtualMachine = ResourceDefinition.builder()
+              .name("[variables('virtualMachineName')]")
+              .type("Microsoft.Compute/virtualMachines")
+              .location(location)
+              .apiVersion(STORAGE_API_VERSION)
+              .dependsOn(Arrays.asList("[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
+                      "[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceCardName'))]"))
+              .tags(ImmutableMap.of("displayName", "VirtualMachine"))
+              .properties(properties)
+              .build();
+
+      resources.add(virtualMachine);
+   }
+
+}