The azure-native:security:Connector resource, part of the Pulumi Azure Native provider, establishes cross-cloud authentication between Azure Security Center and AWS or GCP accounts. This guide focuses on three capabilities: AWS authentication via IAM roles and access keys, GCP service account integration, and hybrid compute management with Arc auto-provisioning.
Connectors require pre-existing cloud credentials and Azure infrastructure. The examples are intentionally small. Combine them with your own IAM roles, service accounts, and resource groups.
Connect AWS accounts using IAM role assumption
Organizations managing security across AWS and Azure often grant Azure Security Center access to AWS resources through IAM role assumption rather than sharing long-lived credentials.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const connector = new azure_native.security.Connector("connector", {
authenticationDetails: {
authenticationType: "awsAssumeRole",
awsAssumeRoleArn: "arn:aws:iam::81231569658:role/AscConnector",
awsExternalId: "20ff7fc3-e762-44dd-bd96-b71116dcdc23",
},
connectorName: "aws_dev2",
hybridComputeSettings: {
autoProvision: azure_native.security.AutoProvision.On,
proxyServer: {
ip: "167.220.197.140",
port: "34",
},
region: "West US 2",
resourceGroupName: "AwsConnectorRG",
servicePrincipal: {
applicationId: "ad9bcd79-be9c-45ab-abd8-80ca1654a7d1",
secret: "<secret>",
},
},
});
import pulumi
import pulumi_azure_native as azure_native
connector = azure_native.security.Connector("connector",
authentication_details={
"authentication_type": "awsAssumeRole",
"aws_assume_role_arn": "arn:aws:iam::81231569658:role/AscConnector",
"aws_external_id": "20ff7fc3-e762-44dd-bd96-b71116dcdc23",
},
connector_name="aws_dev2",
hybrid_compute_settings={
"auto_provision": azure_native.security.AutoProvision.ON,
"proxy_server": {
"ip": "167.220.197.140",
"port": "34",
},
"region": "West US 2",
"resource_group_name": "AwsConnectorRG",
"service_principal": {
"application_id": "ad9bcd79-be9c-45ab-abd8-80ca1654a7d1",
"secret": "<secret>",
},
})
package main
import (
security "github.com/pulumi/pulumi-azure-native-sdk/security/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := security.NewConnector(ctx, "connector", &security.ConnectorArgs{
AuthenticationDetails: &security.AwAssumeRoleAuthenticationDetailsPropertiesArgs{
AuthenticationType: pulumi.String("awsAssumeRole"),
AwsAssumeRoleArn: pulumi.String("arn:aws:iam::81231569658:role/AscConnector"),
AwsExternalId: pulumi.String("20ff7fc3-e762-44dd-bd96-b71116dcdc23"),
},
ConnectorName: pulumi.String("aws_dev2"),
HybridComputeSettings: &security.HybridComputeSettingsPropertiesArgs{
AutoProvision: pulumi.String(security.AutoProvisionOn),
ProxyServer: &security.ProxyServerPropertiesArgs{
Ip: pulumi.String("167.220.197.140"),
Port: pulumi.String("34"),
},
Region: pulumi.String("West US 2"),
ResourceGroupName: pulumi.String("AwsConnectorRG"),
ServicePrincipal: &security.ServicePrincipalPropertiesArgs{
ApplicationId: pulumi.String("ad9bcd79-be9c-45ab-abd8-80ca1654a7d1"),
Secret: pulumi.String("<secret>"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var connector = new AzureNative.Security.Connector("connector", new()
{
AuthenticationDetails = new AzureNative.Security.Inputs.AwAssumeRoleAuthenticationDetailsPropertiesArgs
{
AuthenticationType = "awsAssumeRole",
AwsAssumeRoleArn = "arn:aws:iam::81231569658:role/AscConnector",
AwsExternalId = "20ff7fc3-e762-44dd-bd96-b71116dcdc23",
},
ConnectorName = "aws_dev2",
HybridComputeSettings = new AzureNative.Security.Inputs.HybridComputeSettingsPropertiesArgs
{
AutoProvision = AzureNative.Security.AutoProvision.On,
ProxyServer = new AzureNative.Security.Inputs.ProxyServerPropertiesArgs
{
Ip = "167.220.197.140",
Port = "34",
},
Region = "West US 2",
ResourceGroupName = "AwsConnectorRG",
ServicePrincipal = new AzureNative.Security.Inputs.ServicePrincipalPropertiesArgs
{
ApplicationId = "ad9bcd79-be9c-45ab-abd8-80ca1654a7d1",
Secret = "<secret>",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.security.Connector;
import com.pulumi.azurenative.security.ConnectorArgs;
import com.pulumi.azurenative.security.inputs.HybridComputeSettingsPropertiesArgs;
import com.pulumi.azurenative.security.inputs.ProxyServerPropertiesArgs;
import com.pulumi.azurenative.security.inputs.ServicePrincipalPropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var connector = new Connector("connector", ConnectorArgs.builder()
.authenticationDetails(AwAssumeRoleAuthenticationDetailsPropertiesArgs.builder()
.authenticationType("awsAssumeRole")
.awsAssumeRoleArn("arn:aws:iam::81231569658:role/AscConnector")
.awsExternalId("20ff7fc3-e762-44dd-bd96-b71116dcdc23")
.build())
.connectorName("aws_dev2")
.hybridComputeSettings(HybridComputeSettingsPropertiesArgs.builder()
.autoProvision("On")
.proxyServer(ProxyServerPropertiesArgs.builder()
.ip("167.220.197.140")
.port("34")
.build())
.region("West US 2")
.resourceGroupName("AwsConnectorRG")
.servicePrincipal(ServicePrincipalPropertiesArgs.builder()
.applicationId("ad9bcd79-be9c-45ab-abd8-80ca1654a7d1")
.secret("<secret>")
.build())
.build())
.build());
}
}
resources:
connector:
type: azure-native:security:Connector
properties:
authenticationDetails:
authenticationType: awsAssumeRole
awsAssumeRoleArn: arn:aws:iam::81231569658:role/AscConnector
awsExternalId: 20ff7fc3-e762-44dd-bd96-b71116dcdc23
connectorName: aws_dev2
hybridComputeSettings:
autoProvision: On
proxyServer:
ip: 167.220.197.140
port: '34'
region: West US 2
resourceGroupName: AwsConnectorRG
servicePrincipal:
applicationId: ad9bcd79-be9c-45ab-abd8-80ca1654a7d1
secret: <secret>
The authenticationDetails block specifies the authentication method. For IAM role assumption, set authenticationType to “awsAssumeRole” and provide the awsAssumeRoleArn pointing to your cross-account IAM role. The awsExternalId acts as a shared secret to prevent confused deputy attacks. The hybridComputeSettings block controls Arc auto-provisioning: when autoProvision is “On”, Azure deploys Arc agents to discovered AWS EC2 instances, placing them in the specified resourceGroupName and region.
Connect AWS accounts using access key credentials
Some environments require direct credential-based authentication when IAM role assumption isn’t available.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const connector = new azure_native.security.Connector("connector", {
authenticationDetails: {
authenticationType: "awsCreds",
awsAccessKeyId: "<awsAccessKeyId>",
awsSecretAccessKey: "<awsSecretAccessKey>",
},
connectorName: "aws_dev1",
hybridComputeSettings: {
autoProvision: azure_native.security.AutoProvision.On,
proxyServer: {
ip: "167.220.197.140",
port: "34",
},
region: "West US 2",
resourceGroupName: "AwsConnectorRG",
servicePrincipal: {
applicationId: "ad9bcd79-be9c-45ab-abd8-80ca1654a7d1",
secret: "<secret>",
},
},
});
import pulumi
import pulumi_azure_native as azure_native
connector = azure_native.security.Connector("connector",
authentication_details={
"authentication_type": "awsCreds",
"aws_access_key_id": "<awsAccessKeyId>",
"aws_secret_access_key": "<awsSecretAccessKey>",
},
connector_name="aws_dev1",
hybrid_compute_settings={
"auto_provision": azure_native.security.AutoProvision.ON,
"proxy_server": {
"ip": "167.220.197.140",
"port": "34",
},
"region": "West US 2",
"resource_group_name": "AwsConnectorRG",
"service_principal": {
"application_id": "ad9bcd79-be9c-45ab-abd8-80ca1654a7d1",
"secret": "<secret>",
},
})
package main
import (
security "github.com/pulumi/pulumi-azure-native-sdk/security/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := security.NewConnector(ctx, "connector", &security.ConnectorArgs{
AuthenticationDetails: &security.AwsCredsAuthenticationDetailsPropertiesArgs{
AuthenticationType: pulumi.String("awsCreds"),
AwsAccessKeyId: pulumi.String("<awsAccessKeyId>"),
AwsSecretAccessKey: pulumi.String("<awsSecretAccessKey>"),
},
ConnectorName: pulumi.String("aws_dev1"),
HybridComputeSettings: &security.HybridComputeSettingsPropertiesArgs{
AutoProvision: pulumi.String(security.AutoProvisionOn),
ProxyServer: &security.ProxyServerPropertiesArgs{
Ip: pulumi.String("167.220.197.140"),
Port: pulumi.String("34"),
},
Region: pulumi.String("West US 2"),
ResourceGroupName: pulumi.String("AwsConnectorRG"),
ServicePrincipal: &security.ServicePrincipalPropertiesArgs{
ApplicationId: pulumi.String("ad9bcd79-be9c-45ab-abd8-80ca1654a7d1"),
Secret: pulumi.String("<secret>"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var connector = new AzureNative.Security.Connector("connector", new()
{
AuthenticationDetails = new AzureNative.Security.Inputs.AwsCredsAuthenticationDetailsPropertiesArgs
{
AuthenticationType = "awsCreds",
AwsAccessKeyId = "<awsAccessKeyId>",
AwsSecretAccessKey = "<awsSecretAccessKey>",
},
ConnectorName = "aws_dev1",
HybridComputeSettings = new AzureNative.Security.Inputs.HybridComputeSettingsPropertiesArgs
{
AutoProvision = AzureNative.Security.AutoProvision.On,
ProxyServer = new AzureNative.Security.Inputs.ProxyServerPropertiesArgs
{
Ip = "167.220.197.140",
Port = "34",
},
Region = "West US 2",
ResourceGroupName = "AwsConnectorRG",
ServicePrincipal = new AzureNative.Security.Inputs.ServicePrincipalPropertiesArgs
{
ApplicationId = "ad9bcd79-be9c-45ab-abd8-80ca1654a7d1",
Secret = "<secret>",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.security.Connector;
import com.pulumi.azurenative.security.ConnectorArgs;
import com.pulumi.azurenative.security.inputs.HybridComputeSettingsPropertiesArgs;
import com.pulumi.azurenative.security.inputs.ProxyServerPropertiesArgs;
import com.pulumi.azurenative.security.inputs.ServicePrincipalPropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var connector = new Connector("connector", ConnectorArgs.builder()
.authenticationDetails(AwsCredsAuthenticationDetailsPropertiesArgs.builder()
.authenticationType("awsCreds")
.awsAccessKeyId("<awsAccessKeyId>")
.awsSecretAccessKey("<awsSecretAccessKey>")
.build())
.connectorName("aws_dev1")
.hybridComputeSettings(HybridComputeSettingsPropertiesArgs.builder()
.autoProvision("On")
.proxyServer(ProxyServerPropertiesArgs.builder()
.ip("167.220.197.140")
.port("34")
.build())
.region("West US 2")
.resourceGroupName("AwsConnectorRG")
.servicePrincipal(ServicePrincipalPropertiesArgs.builder()
.applicationId("ad9bcd79-be9c-45ab-abd8-80ca1654a7d1")
.secret("<secret>")
.build())
.build())
.build());
}
}
resources:
connector:
type: azure-native:security:Connector
properties:
authenticationDetails:
authenticationType: awsCreds
awsAccessKeyId: <awsAccessKeyId>
awsSecretAccessKey: <awsSecretAccessKey>
connectorName: aws_dev1
hybridComputeSettings:
autoProvision: On
proxyServer:
ip: 167.220.197.140
port: '34'
region: West US 2
resourceGroupName: AwsConnectorRG
servicePrincipal:
applicationId: ad9bcd79-be9c-45ab-abd8-80ca1654a7d1
secret: <secret>
The authenticationType switches to “awsCreds” for static credential authentication. Instead of a role ARN, you provide awsAccessKeyId and awsSecretAccessKey directly. The hybridComputeSettings remain similar, enabling Arc agent deployment to AWS instances. This approach trades the security benefits of temporary credentials for simpler setup in constrained environments.
Connect GCP projects using service account credentials
Multi-cloud security monitoring extends to Google Cloud Platform through service account authentication.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const connector = new azure_native.security.Connector("connector", {
authenticationDetails: {
authProviderX509CertUrl: "https://www.googleapis.com/oauth2/v1/certs",
authUri: "https://accounts.google.com/o/oauth2/auth",
authenticationType: "gcpCredentials",
clientEmail: "asc-135@asc-project-1234.iam.gserviceaccount.com",
clientId: "105889053725632919854",
clientX509CertUrl: "https://www.googleapis.com/robot/v1/metadata/x509/asc-135%40asc-project-1234.iam.gserviceaccount.com",
organizationId: "AscDemoOrg",
privateKey: "******",
privateKeyId: "6efg587hra2568as34d22326b044cc20dc2af",
projectId: "asc-project-1234",
tokenUri: "https://oauth2.googleapis.com/token",
type: "service_account",
},
connectorName: "gcp_dev",
hybridComputeSettings: {
autoProvision: azure_native.security.AutoProvision.Off,
},
});
import pulumi
import pulumi_azure_native as azure_native
connector = azure_native.security.Connector("connector",
authentication_details={
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"authentication_type": "gcpCredentials",
"client_email": "asc-135@asc-project-1234.iam.gserviceaccount.com",
"client_id": "105889053725632919854",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/asc-135%40asc-project-1234.iam.gserviceaccount.com",
"organization_id": "AscDemoOrg",
"private_key": "******",
"private_key_id": "6efg587hra2568as34d22326b044cc20dc2af",
"project_id": "asc-project-1234",
"token_uri": "https://oauth2.googleapis.com/token",
"type": "service_account",
},
connector_name="gcp_dev",
hybrid_compute_settings={
"auto_provision": azure_native.security.AutoProvision.OFF,
})
package main
import (
security "github.com/pulumi/pulumi-azure-native-sdk/security/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := security.NewConnector(ctx, "connector", &security.ConnectorArgs{
AuthenticationDetails: &security.GcpCredentialsDetailsPropertiesArgs{
AuthProviderX509CertUrl: pulumi.String("https://www.googleapis.com/oauth2/v1/certs"),
AuthUri: pulumi.String("https://accounts.google.com/o/oauth2/auth"),
AuthenticationType: pulumi.String("gcpCredentials"),
ClientEmail: pulumi.String("asc-135@asc-project-1234.iam.gserviceaccount.com"),
ClientId: pulumi.String("105889053725632919854"),
ClientX509CertUrl: pulumi.String("https://www.googleapis.com/robot/v1/metadata/x509/asc-135%40asc-project-1234.iam.gserviceaccount.com"),
OrganizationId: pulumi.String("AscDemoOrg"),
PrivateKey: pulumi.String("******"),
PrivateKeyId: pulumi.String("6efg587hra2568as34d22326b044cc20dc2af"),
ProjectId: pulumi.String("asc-project-1234"),
TokenUri: pulumi.String("https://oauth2.googleapis.com/token"),
Type: pulumi.String("service_account"),
},
ConnectorName: pulumi.String("gcp_dev"),
HybridComputeSettings: &security.HybridComputeSettingsPropertiesArgs{
AutoProvision: pulumi.String(security.AutoProvisionOff),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var connector = new AzureNative.Security.Connector("connector", new()
{
AuthenticationDetails = new AzureNative.Security.Inputs.GcpCredentialsDetailsPropertiesArgs
{
AuthProviderX509CertUrl = "https://www.googleapis.com/oauth2/v1/certs",
AuthUri = "https://accounts.google.com/o/oauth2/auth",
AuthenticationType = "gcpCredentials",
ClientEmail = "asc-135@asc-project-1234.iam.gserviceaccount.com",
ClientId = "105889053725632919854",
ClientX509CertUrl = "https://www.googleapis.com/robot/v1/metadata/x509/asc-135%40asc-project-1234.iam.gserviceaccount.com",
OrganizationId = "AscDemoOrg",
PrivateKey = "******",
PrivateKeyId = "6efg587hra2568as34d22326b044cc20dc2af",
ProjectId = "asc-project-1234",
TokenUri = "https://oauth2.googleapis.com/token",
Type = "service_account",
},
ConnectorName = "gcp_dev",
HybridComputeSettings = new AzureNative.Security.Inputs.HybridComputeSettingsPropertiesArgs
{
AutoProvision = AzureNative.Security.AutoProvision.Off,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.security.Connector;
import com.pulumi.azurenative.security.ConnectorArgs;
import com.pulumi.azurenative.security.inputs.HybridComputeSettingsPropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var connector = new Connector("connector", ConnectorArgs.builder()
.authenticationDetails(GcpCredentialsDetailsPropertiesArgs.builder()
.authProviderX509CertUrl("https://www.googleapis.com/oauth2/v1/certs")
.authUri("https://accounts.google.com/o/oauth2/auth")
.authenticationType("gcpCredentials")
.clientEmail("asc-135@asc-project-1234.iam.gserviceaccount.com")
.clientId("105889053725632919854")
.clientX509CertUrl("https://www.googleapis.com/robot/v1/metadata/x509/asc-135%40asc-project-1234.iam.gserviceaccount.com")
.organizationId("AscDemoOrg")
.privateKey("******")
.privateKeyId("6efg587hra2568as34d22326b044cc20dc2af")
.projectId("asc-project-1234")
.tokenUri("https://oauth2.googleapis.com/token")
.type("service_account")
.build())
.connectorName("gcp_dev")
.hybridComputeSettings(HybridComputeSettingsPropertiesArgs.builder()
.autoProvision("Off")
.build())
.build());
}
}
resources:
connector:
type: azure-native:security:Connector
properties:
authenticationDetails:
authProviderX509CertUrl: https://www.googleapis.com/oauth2/v1/certs
authUri: https://accounts.google.com/o/oauth2/auth
authenticationType: gcpCredentials
clientEmail: asc-135@asc-project-1234.iam.gserviceaccount.com
clientId: '105889053725632919854'
clientX509CertUrl: https://www.googleapis.com/robot/v1/metadata/x509/asc-135%40asc-project-1234.iam.gserviceaccount.com
organizationId: AscDemoOrg
privateKey: '******'
privateKeyId: 6efg587hra2568as34d22326b044cc20dc2af
projectId: asc-project-1234
tokenUri: https://oauth2.googleapis.com/token
type: service_account
connectorName: gcp_dev
hybridComputeSettings:
autoProvision: Off
GCP authentication uses authenticationType “gcpCredentials” and requires the full service account JSON key contents: clientEmail, privateKey, projectId, and organizationId identify the GCP resources to monitor. The authUri, tokenUri, and certificate URLs define OAuth2 endpoints for token exchange. Setting autoProvision to “Off” disables Arc agent deployment, limiting the connector to security assessment without hybrid compute management.
Beyond these examples
These snippets focus on specific connector features: AWS authentication (IAM role assumption and access keys), GCP service account integration, and hybrid compute management with Arc auto-provisioning. They’re intentionally minimal rather than complete multi-cloud security deployments.
The examples reference pre-existing infrastructure such as AWS IAM roles or access keys with Security Center permissions, GCP service accounts with organization-level access, Azure resource groups for Arc-managed resources, and Azure service principals for hybrid compute provisioning. They focus on configuring the connector rather than provisioning the surrounding cloud identity infrastructure.
To keep things focused, common connector patterns are omitted, including:
- Connector lifecycle management (updates, deletion)
- Authentication credential rotation
- Network proxy configuration details
- Multi-region or multi-account strategies
These omissions are intentional: the goal is to illustrate how each authentication method is wired, not provide drop-in multi-cloud security modules. See the Security Connector resource reference for all available configuration options.
Let's configure Azure Security Connectors
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Authentication & Cloud Providers
awsAssumeRole and awsCreds), while GCP uses service account credentials (gcpCredentials).awsAssumeRole uses an IAM role ARN with an external ID for cross-account access, while awsCreds uses AWS access key and secret key directly. AssumeRole is generally preferred for security.clientEmail, privateKey, projectId, organizationId, and OAuth URIs (authUri, tokenUri, certificate URLs).Hybrid Compute & Azure Arc
autoProvision to On. The service principal requires an applicationId and secret for creating Arc resources.autoProvision: Off with minimal settings, while AWS examples include full Arc configuration.Configuration & Limitations
connectorName is immutable and cannot be changed after creation. Changing it requires recreating the connector.West US 2). This determines where the resourceGroupName is located.proxyServer within hybridComputeSettings to specify an ip and port for proxy communication.