A Pulumi provider SDK for creating and managing Amazon Web Services (AWS) cloud resources in Go, providing strongly-typed resource classes and data sources for all major AWS services.
Production-ready examples demonstrating complete infrastructure patterns using the Pulumi AWS Provider.
Deploy a complete serverless API with Lambda backend, API Gateway frontend, and proper IAM permissions.
package main
import (
"encoding/json"
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigatewayv2"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// 1. Create Lambda execution role
assumeRolePolicy, _ := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{{
"Effect": "Allow",
"Principal": map[string]string{"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole",
}},
})
role, err := iam.NewRole(ctx, "lambda-role", &iam.RoleArgs{
AssumeRolePolicy: pulumi.String(string(assumeRolePolicy)),
})
if err != nil {
return err
}
// Attach basic execution policy
_, err = iam.NewRolePolicyAttachment(ctx, "lambda-exec", &iam.RolePolicyAttachmentArgs{
Role: role.Name,
PolicyArn: pulumi.String("arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"),
})
if err != nil {
return err
}
// 2. Create Lambda function
fn, err := lambda.NewFunction(ctx, "api-handler", &lambda.FunctionArgs{
Runtime: pulumi.String("nodejs20.x"),
Handler: pulumi.String("index.handler"),
Role: role.Arn,
Code: pulumi.NewFileArchive("./function"),
Environment: &lambda.FunctionEnvironmentArgs{
Variables: pulumi.StringMap{
"STAGE": pulumi.String("production"),
},
},
}, pulumi.DependsOn([]pulumi.Resource{role}))
if err != nil {
return err
}
// 3. Create API Gateway HTTP API
api, err := apigatewayv2.NewApi(ctx, "api", &apigatewayv2.ApiArgs{
Name: pulumi.String("my-api"),
ProtocolType: pulumi.String("HTTP"),
CorsConfiguration: &apigatewayv2.ApiCorsConfigurationArgs{
AllowOrigins: pulumi.StringArray{pulumi.String("*")},
AllowMethods: pulumi.StringArray{pulumi.String("*")},
},
})
if err != nil {
return err
}
// 4. Create integration
integration, err := apigatewayv2.NewIntegration(ctx, "integration", &apigatewayv2.IntegrationArgs{
ApiId: api.ID(),
IntegrationType: pulumi.String("AWS_PROXY"),
IntegrationUri: fn.InvokeArn,
IntegrationMethod: pulumi.String("POST"),
PayloadFormatVersion: pulumi.String("2.0"),
})
if err != nil {
return err
}
// 5. Create route
_, err = apigatewayv2.NewRoute(ctx, "route", &apigatewayv2.RouteArgs{
ApiId: api.ID(),
RouteKey: pulumi.String("POST /api"),
Target: integration.ID().ApplyT(func(id string) string {
return fmt.Sprintf("integrations/%s", id)
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
// 6. Create stage (auto-deploy)
stage, err := apigatewayv2.NewStage(ctx, "stage", &apigatewayv2.StageArgs{
ApiId: api.ID(),
Name: pulumi.String("$default"),
AutoDeploy: pulumi.Bool(true),
})
if err != nil {
return err
}
// 7. Grant API Gateway permission to invoke Lambda
_, err = lambda.NewPermission(ctx, "api-permission", &lambda.PermissionArgs{
Action: pulumi.String("lambda:InvokeFunction"),
Function: fn.Name,
Principal: pulumi.String("apigateway.amazonaws.com"),
SourceArn: api.ExecutionArn.ApplyT(func(arn string) string {
return fmt.Sprintf("%s/*/*", arn)
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
// Export API endpoint
ctx.Export("apiEndpoint", stage.InvokeUrl)
ctx.Export("functionArn", fn.Arn)
return nil
})
}Deploy a production static website with CDN, custom domain, and HTTPS.
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/acm"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudfront"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/route53"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
domain := "example.com"
// 1. Create S3 bucket for website content
bucket, err := s3.NewBucketV2(ctx, "website-bucket", &s3.BucketV2Args{
Bucket: pulumi.Sprintf("%s-website", domain),
})
if err != nil {
return err
}
// Block public access (CloudFront will access via OAI)
_, err = s3.NewBucketPublicAccessBlock(ctx, "bucket-pab", &s3.BucketPublicAccessBlockArgs{
Bucket: bucket.ID(),
BlockPublicAcls: pulumi.Bool(true),
BlockPublicPolicy: pulumi.Bool(true),
IgnorePublicAcls: pulumi.Bool(true),
RestrictPublicBuckets: pulumi.Bool(true),
})
if err != nil {
return err
}
// 2. Create ACM certificate (MUST be in us-east-1 for CloudFront)
usEast1, err := aws.NewProvider(ctx, "us-east-1", &aws.ProviderArgs{
Region: pulumi.StringPtr("us-east-1"),
})
if err != nil {
return err
}
cert, err := acm.NewCertificate(ctx, "cert", &acm.CertificateArgs{
DomainName: pulumi.String(domain),
ValidationMethod: pulumi.String("DNS"),
}, pulumi.Provider(usEast1))
if err != nil {
return err
}
// 3. Lookup Route53 hosted zone
zone, err := route53.LookupZone(ctx, &route53.LookupZoneArgs{
Name: pulumi.StringRef(domain),
})
if err != nil {
return err
}
// 4. Create CloudFront distribution
distribution, err := cloudfront.NewDistribution(ctx, "cdn", &cloudfront.DistributionArgs{
Enabled: pulumi.Bool(true),
DefaultRootObject: pulumi.String("index.html"),
Origins: cloudfront.DistributionOriginArray{
&cloudfront.DistributionOriginArgs{
DomainName: bucket.BucketDomainName,
OriginId: pulumi.String("S3Origin"),
},
},
DefaultCacheBehavior: &cloudfront.DistributionDefaultCacheBehaviorArgs{
TargetOriginId: pulumi.String("S3Origin"),
ViewerProtocolPolicy: pulumi.String("redirect-to-https"),
AllowedMethods: pulumi.StringArray{
pulumi.String("GET"),
pulumi.String("HEAD"),
pulumi.String("OPTIONS"),
},
CachedMethods: pulumi.StringArray{
pulumi.String("GET"),
pulumi.String("HEAD"),
},
ForwardedValues: &cloudfront.DistributionDefaultCacheBehaviorForwardedValuesArgs{
QueryString: pulumi.Bool(false),
Cookies: &cloudfront.DistributionDefaultCacheBehaviorForwardedValuesCookiesArgs{
Forward: pulumi.String("none"),
},
},
},
ViewerCertificate: &cloudfront.DistributionViewerCertificateArgs{
AcmCertificateArn: cert.Arn,
SslSupportMethod: pulumi.String("sni-only"),
},
Aliases: pulumi.StringArray{pulumi.String(domain)},
})
if err != nil {
return err
}
// 5. Create Route53 alias record
_, err = route53.NewRecord(ctx, "www-record", &route53.RecordArgs{
ZoneId: pulumi.String(zone.ZoneId),
Name: pulumi.String(domain),
Type: pulumi.String("A"),
Aliases: route53.RecordAliasArray{
&route53.RecordAliasArgs{
Name: distribution.DomainName,
ZoneId: distribution.HostedZoneId,
EvaluateTargetHealth: pulumi.Bool(false),
},
},
})
if err != nil {
return err
}
ctx.Export("websiteUrl", pulumi.Sprintf("https://%s", domain))
ctx.Export("bucketName", bucket.Bucket)
ctx.Export("distributionId", distribution.ID())
return nil
})
}Deploy a containerized application with Elastic Container Service and Application Load Balancer.
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecs"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lb"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// Get availability zones
azs, err := aws.GetAvailabilityZones(ctx, &aws.GetAvailabilityZonesArgs{
State: pulumi.StringRef("available"),
}, nil)
if err != nil {
return err
}
// 1. Create VPC and networking
vpc, err := ec2.NewVpc(ctx, "vpc", &ec2.VpcArgs{
CidrBlock: pulumi.String("10.0.0.0/16"),
EnableDnsHostnames: pulumi.Bool(true),
})
if err != nil {
return err
}
// Create subnets in multiple AZs
subnets := make([]*ec2.Subnet, 0)
for i := 0; i < 2; i++ {
subnet, err := ec2.NewSubnet(ctx, fmt.Sprintf("subnet-%d", i), &ec2.SubnetArgs{
VpcId: vpc.ID(),
CidrBlock: pulumi.Sprintf("10.0.%d.0/24", i+1),
AvailabilityZone: pulumi.String(azs.Names[i]),
MapPublicIpOnLaunch: pulumi.Bool(true),
})
if err != nil {
return err
}
subnets = append(subnets, subnet)
}
// 2. Create security groups
albSg, err := ec2.NewSecurityGroup(ctx, "alb-sg", &ec2.SecurityGroupArgs{
VpcId: vpc.ID(),
Ingress: ec2.SecurityGroupIngressArray{
&ec2.SecurityGroupIngressArgs{
Protocol: pulumi.String("tcp"),
FromPort: pulumi.Int(80),
ToPort: pulumi.Int(80),
CidrBlocks: pulumi.StringArray{pulumi.String("0.0.0.0/0")},
},
},
})
if err != nil {
return err
}
ecsSg, err := ec2.NewSecurityGroup(ctx, "ecs-sg", &ec2.SecurityGroupArgs{
VpcId: vpc.ID(),
})
if err != nil {
return err
}
// Allow ALB to reach ECS
_, err = ec2.NewSecurityGroupRule(ctx, "ecs-from-alb", &ec2.SecurityGroupRuleArgs{
Type: pulumi.String("ingress"),
SecurityGroupId: ecsSg.ID(),
SourceSecurityGroupId: albSg.ID(),
Protocol: pulumi.String("tcp"),
FromPort: pulumi.Int(80),
ToPort: pulumi.Int(80),
})
if err != nil {
return err
}
// 3. Create ALB
alb, err := lb.NewLoadBalancer(ctx, "alb", &lb.LoadBalancerArgs{
LoadBalancerType: pulumi.String("application"),
SecurityGroups: pulumi.StringArray{albSg.ID()},
Subnets: pulumi.StringArray{
subnets[0].ID(),
subnets[1].ID(),
},
})
if err != nil {
return err
}
// Target group
tg, err := lb.NewTargetGroup(ctx, "tg", &lb.TargetGroupArgs{
Port: pulumi.Int(80),
Protocol: pulumi.String("HTTP"),
VpcId: vpc.ID(),
TargetType: pulumi.String("ip"),
HealthCheck: &lb.TargetGroupHealthCheckArgs{
Path: pulumi.String("/health"),
Matcher: pulumi.String("200"),
},
})
if err != nil {
return err
}
// Listener
_, err = lb.NewListener(ctx, "listener", &lb.ListenerArgs{
LoadBalancerArn: alb.Arn,
Port: pulumi.Int(80),
Protocol: pulumi.String("HTTP"),
DefaultActions: lb.ListenerDefaultActionArray{
&lb.ListenerDefaultActionArgs{
Type: pulumi.String("forward"),
TargetGroupArn: tg.Arn,
},
},
})
if err != nil {
return err
}
// 4. Create ECS cluster
cluster, err := ecs.NewCluster(ctx, "cluster", &ecs.ClusterArgs{
Name: pulumi.String("my-cluster"),
})
if err != nil {
return err
}
// ECS task execution role
taskAssumePolicy, _ := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{{
"Effect": "Allow",
"Principal": map[string]string{"Service": "ecs-tasks.amazonaws.com"},
"Action": "sts:AssumeRole",
}},
})
taskRole, err := iam.NewRole(ctx, "task-role", &iam.RoleArgs{
AssumeRolePolicy: pulumi.String(string(taskAssumePolicy)),
})
if err != nil {
return err
}
_, err = iam.NewRolePolicyAttachment(ctx, "task-exec-policy", &iam.RolePolicyAttachmentArgs{
Role: taskRole.Name,
PolicyArn: pulumi.String("arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"),
})
if err != nil {
return err
}
// Task definition
containerDefs, _ := json.Marshal([]map[string]interface{}{{
"name": "app",
"image": "nginx:latest",
"cpu": 256,
"memory": 512,
"essential": true,
"portMappings": []map[string]interface{}{{
"containerPort": 80,
"protocol": "tcp",
}},
}})
taskDef, err := ecs.NewTaskDefinition(ctx, "task", &ecs.TaskDefinitionArgs{
Family: pulumi.String("my-app"),
Cpu: pulumi.String("256"),
Memory: pulumi.String("512"),
NetworkMode: pulumi.String("awsvpc"),
RequiresCompatibilities: pulumi.StringArray{pulumi.String("FARGATE")},
ExecutionRoleArn: taskRole.Arn,
ContainerDefinitions: pulumi.String(string(containerDefs)),
})
if err != nil {
return err
}
// ECS service
_, err = ecs.NewService(ctx, "service", &ecs.ServiceArgs{
Cluster: cluster.Arn,
TaskDefinition: taskDef.Arn,
DesiredCount: pulumi.Int(2),
LaunchType: pulumi.String("FARGATE"),
NetworkConfiguration: &ecs.ServiceNetworkConfigurationArgs{
Subnets: pulumi.StringArray{subnets[0].ID(), subnets[1].ID()},
SecurityGroups: pulumi.StringArray{ecsSg.ID()},
AssignPublicIp: pulumi.Bool(true),
},
LoadBalancers: ecs.ServiceLoadBalancerArray{
&ecs.ServiceLoadBalancerArgs{
TargetGroupArn: tg.Arn,
ContainerName: pulumi.String("app"),
ContainerPort: pulumi.Int(80),
},
},
})
if err != nil {
return err
}
ctx.Export("albDns", alb.DnsName)
ctx.Export("clusterName", cluster.Name)
return nil
})
}Production-ready VPC with public and private subnets across multiple availability zones.
package main
import (
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// Get available AZs
azs, err := aws.GetAvailabilityZones(ctx, &aws.GetAvailabilityZonesArgs{
State: pulumi.StringRef("available"),
}, nil)
if err != nil {
return err
}
// Create VPC
vpc, err := ec2.NewVpc(ctx, "main", &ec2.VpcArgs{
CidrBlock: pulumi.String("10.0.0.0/16"),
EnableDnsHostnames: pulumi.Bool(true),
EnableDnsSupport: pulumi.Bool(true),
})
if err != nil {
return err
}
// Internet Gateway
igw, err := ec2.NewInternetGateway(ctx, "igw", &ec2.InternetGatewayArgs{
VpcId: vpc.ID(),
})
if err != nil {
return err
}
// Create public and private subnets in each AZ
publicSubnets := make([]*ec2.Subnet, 0)
privateSubnets := make([]*ec2.Subnet, 0)
for i := 0; i < 2 && i < len(azs.Names); i++ {
// Public subnet
pubSubnet, err := ec2.NewSubnet(ctx, fmt.Sprintf("public-%d", i), &ec2.SubnetArgs{
VpcId: vpc.ID(),
CidrBlock: pulumi.Sprintf("10.0.%d.0/24", i+1),
AvailabilityZone: pulumi.String(azs.Names[i]),
MapPublicIpOnLaunch: pulumi.Bool(true),
})
if err != nil {
return err
}
publicSubnets = append(publicSubnets, pubSubnet)
// Private subnet
privSubnet, err := ec2.NewSubnet(ctx, fmt.Sprintf("private-%d", i), &ec2.SubnetArgs{
VpcId: vpc.ID(),
CidrBlock: pulumi.Sprintf("10.0.%d.0/24", i+10),
AvailabilityZone: pulumi.String(azs.Names[i]),
})
if err != nil {
return err
}
privateSubnets = append(privateSubnets, privSubnet)
}
// NAT Gateway for private subnets
eip, err := ec2.NewEip(ctx, "nat-eip", &ec2.EipArgs{
Domain: pulumi.String("vpc"),
}, pulumi.DependsOn([]pulumi.Resource{igw}))
if err != nil {
return err
}
natGw, err := ec2.NewNatGateway(ctx, "nat", &ec2.NatGatewayArgs{
AllocationId: eip.AllocationId,
SubnetId: publicSubnets[0].ID(),
})
if err != nil {
return err
}
// Public route table
pubRt, err := ec2.NewRouteTable(ctx, "public-rt", &ec2.RouteTableArgs{
VpcId: vpc.ID(),
})
if err != nil {
return err
}
_, err = ec2.NewRoute(ctx, "public-route", &ec2.RouteArgs{
RouteTableId: pubRt.ID(),
DestinationCidrBlock: pulumi.String("0.0.0.0/0"),
GatewayId: igw.ID(),
})
if err != nil {
return err
}
// Private route table
privRt, err := ec2.NewRouteTable(ctx, "private-rt", &ec2.RouteTableArgs{
VpcId: vpc.ID(),
})
if err != nil {
return err
}
_, err = ec2.NewRoute(ctx, "private-route", &ec2.RouteArgs{
RouteTableId: privRt.ID(),
DestinationCidrBlock: pulumi.String("0.0.0.0/0"),
NatGatewayId: natGw.ID(),
})
if err != nil {
return err
}
// Associate subnets with route tables
for i, subnet := range publicSubnets {
_, err = ec2.NewRouteTableAssociation(ctx, fmt.Sprintf("pub-rta-%d", i), &ec2.RouteTableAssociationArgs{
SubnetId: subnet.ID(),
RouteTableId: pubRt.ID(),
})
if err != nil {
return err
}
}
for i, subnet := range privateSubnets {
_, err = ec2.NewRouteTableAssociation(ctx, fmt.Sprintf("priv-rta-%d", i), &ec2.RouteTableAssociationArgs{
SubnetId: subnet.ID(),
RouteTableId: privRt.ID(),
})
if err != nil {
return err
}
}
// VPC Endpoints (save NAT costs)
_, err = ec2.NewVpcEndpoint(ctx, "s3-endpoint", &ec2.VpcEndpointArgs{
VpcId: vpc.ID(),
ServiceName: pulumi.String("com.amazonaws.us-east-1.s3"),
VpcEndpointType: pulumi.String("Gateway"),
RouteTableIds: pulumi.StringArray{privRt.ID()},
})
if err != nil {
return err
}
ctx.Export("vpcId", vpc.ID())
return nil
})
}Process DynamoDB changes with Lambda in real-time.
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/dynamodb"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// 1. Create DynamoDB table with stream
table, err := dynamodb.NewTable(ctx, "events", &dynamodb.TableArgs{
HashKey: pulumi.String("eventId"),
BillingMode: pulumi.String("PAY_PER_REQUEST"),
StreamEnabled: pulumi.Bool(true),
StreamViewType: pulumi.String("NEW_AND_OLD_IMAGES"),
Attributes: dynamodb.TableAttributeArray{
&dynamodb.TableAttributeArgs{
Name: pulumi.String("eventId"),
Type: pulumi.String("S"),
},
},
})
if err != nil {
return err
}
// 2. Create Lambda role with DynamoDB Stream permissions
assumeRolePolicy, _ := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{{
"Effect": "Allow",
"Principal": map[string]string{"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole",
}},
})
role, err := iam.NewRole(ctx, "processor-role", &iam.RoleArgs{
AssumeRolePolicy: pulumi.String(string(assumeRolePolicy)),
})
if err != nil {
return err
}
// Attach Lambda execution policy
_, err = iam.NewRolePolicyAttachment(ctx, "lambda-exec", &iam.RolePolicyAttachmentArgs{
Role: role.Name,
PolicyArn: pulumi.String("arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"),
})
if err != nil {
return err
}
// Attach DynamoDB Stream read policy
streamPolicy, _ := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{{
"Effect": "Allow",
"Action": []string{
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:DescribeStream",
"dynamodb:ListStreams",
},
"Resource": "*",
}},
})
policy, err := iam.NewPolicy(ctx, "stream-policy", &iam.PolicyArgs{
Policy: pulumi.String(string(streamPolicy)),
})
if err != nil {
return err
}
_, err = iam.NewRolePolicyAttachment(ctx, "stream-attach", &iam.RolePolicyAttachmentArgs{
Role: role.Name,
PolicyArn: policy.Arn,
})
if err != nil {
return err
}
// 3. Create Lambda function
fn, err := lambda.NewFunction(ctx, "processor", &lambda.FunctionArgs{
Runtime: pulumi.String("python3.12"),
Handler: pulumi.String("index.handler"),
Role: role.Arn,
Code: pulumi.NewFileArchive("./processor"),
})
if err != nil {
return err
}
// 4. Create event source mapping
_, err = lambda.NewEventSourceMapping(ctx, "stream-mapping", &lambda.EventSourceMappingArgs{
EventSourceArn: table.StreamArn,
FunctionName: fn.Arn,
StartingPosition: pulumi.String("LATEST"),
BatchSize: pulumi.IntPtr(100),
MaximumBatchingWindowInSeconds: pulumi.IntPtr(5),
FunctionResponseTypes: pulumi.StringArray{
pulumi.String("ReportBatchItemFailures"),
},
})
if err != nil {
return err
}
ctx.Export("tableName", table.Name)
ctx.Export("streamArn", table.StreamArn)
ctx.Export("functionName", fn.Name)
return nil
})
}Deploy resources across multiple AWS regions.
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
regions := []string{"us-east-1", "us-west-2", "eu-west-1"}
for _, region := range regions {
// Create provider for each region
provider, err := aws.NewProvider(ctx, fmt.Sprintf("provider-%s", region), &aws.ProviderArgs{
Region: pulumi.StringPtr(region),
})
if err != nil {
return err
}
// Create bucket in each region
bucket, err := s3.NewBucketV2(ctx, fmt.Sprintf("bucket-%s", region), &s3.BucketV2Args{
Bucket: pulumi.Sprintf("my-app-%s", region),
Tags: pulumi.StringMap{
"Region": pulumi.String(region),
},
}, pulumi.Provider(provider))
if err != nil {
return err
}
// Export bucket name
ctx.Export(fmt.Sprintf("bucket%s", region), bucket.Bucket)
}
return nil
})
}Manage resources across multiple AWS accounts.
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// Main account provider
mainProvider, err := aws.NewProvider(ctx, "main", &aws.ProviderArgs{
Region: pulumi.StringPtr("us-east-1"),
Profile: pulumi.StringPtr("main-account"),
})
if err != nil {
return err
}
// Dev account provider (via role assumption)
devProvider, err := aws.NewProvider(ctx, "dev", &aws.ProviderArgs{
Region: pulumi.StringPtr("us-east-1"),
AssumeRoles: aws.ProviderAssumeRoleArray{
&aws.ProviderAssumeRoleArgs{
RoleArn: pulumi.StringPtr("arn:aws:iam::111111111111:role/DevDeployRole"),
SessionName: pulumi.StringPtr("PulumiDevSession"),
ExternalId: pulumi.StringPtr("dev-external-id"),
},
},
})
if err != nil {
return err
}
// Resources in main account
mainBucket, err := s3.NewBucketV2(ctx, "main-bucket", &s3.BucketV2Args{
Bucket: pulumi.String("main-account-bucket"),
}, pulumi.Provider(mainProvider))
if err != nil {
return err
}
// Resources in dev account
devBucket, err := s3.NewBucketV2(ctx, "dev-bucket", &s3.BucketV2Args{
Bucket: pulumi.String("dev-account-bucket"),
}, pulumi.Provider(devProvider))
if err != nil {
return err
}
ctx.Export("mainBucket", mainBucket.Bucket)
ctx.Export("devBucket", devBucket.Bucket)
return nil
})
}Deploy RDS database with KMS encryption, subnet group, and security.
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/rds"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// 1. Create KMS key for encryption
key, err := kms.NewKey(ctx, "db-key", &kms.KeyArgs{
Description: pulumi.String("RDS encryption key"),
EnableKeyRotation: pulumi.Bool(true),
DeletionWindowInDays: pulumi.Int(10),
})
if err != nil {
return err
}
// 2. Create subnet group
subnetGroup, err := rds.NewSubnetGroup(ctx, "db-subnets", &rds.SubnetGroupArgs{
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-12345"),
pulumi.String("subnet-67890"),
},
})
if err != nil {
return err
}
// 3. Create security group
dbSg, err := ec2.NewSecurityGroup(ctx, "db-sg", &ec2.SecurityGroupArgs{
VpcId: pulumi.String("vpc-12345"),
Description: pulumi.String("Database security group"),
Ingress: ec2.SecurityGroupIngressArray{
&ec2.SecurityGroupIngressArgs{
Protocol: pulumi.String("tcp"),
FromPort: pulumi.Int(5432),
ToPort: pulumi.Int(5432),
CidrBlocks: pulumi.StringArray{pulumi.String("10.0.0.0/16")},
},
},
})
if err != nil {
return err
}
// 4. Create RDS instance
db, err := rds.NewInstance(ctx, "postgres", &rds.InstanceArgs{
AllocatedStorage: pulumi.Int(20),
Engine: pulumi.String("postgres"),
EngineVersion: pulumi.String("15.3"),
InstanceClass: pulumi.String("db.t3.micro"),
DbName: pulumi.String("mydb"),
Username: pulumi.String("admin"),
Password: pulumi.String("SecurePassword123!"), // Use Secrets Manager in production
DbSubnetGroupName: subnetGroup.Name,
VpcSecurityGroupIds: pulumi.StringArray{dbSg.ID()},
StorageEncrypted: pulumi.Bool(true),
KmsKeyId: key.Arn,
BackupRetentionPeriod: pulumi.Int(7),
MultiAz: pulumi.Bool(true),
SkipFinalSnapshot: pulumi.Bool(true),
})
if err != nil {
return err
}
ctx.Export("dbEndpoint", db.Endpoint)
ctx.Export("dbName", db.DbName)
return nil
})
}Set up comprehensive CloudWatch monitoring with alarms.
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sns"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// 1. Create SNS topic for alerts
topic, err := sns.NewTopic(ctx, "alerts", &sns.TopicArgs{
Name: pulumi.String("infrastructure-alerts"),
})
if err != nil {
return err
}
// 2. Create CloudWatch Log Group
logGroup, err := cloudwatch.NewLogGroup(ctx, "app-logs", &cloudwatch.LogGroupArgs{
Name: pulumi.String("/aws/app/production"),
RetentionInDays: pulumi.Int(7),
})
if err != nil {
return err
}
// 3. Create metric alarm
_, err = cloudwatch.NewMetricAlarm(ctx, "high-cpu", &cloudwatch.MetricAlarmArgs{
Name: pulumi.String("high-cpu-utilization"),
ComparisonOperator: pulumi.String("GreaterThanThreshold"),
EvaluationPeriods: pulumi.Int(2),
MetricName: pulumi.String("CPUUtilization"),
Namespace: pulumi.String("AWS/EC2"),
Period: pulumi.Int(120),
Statistic: pulumi.String("Average"),
Threshold: pulumi.Float64(80),
AlarmActions: pulumi.Array{
topic.Arn,
},
})
if err != nil {
return err
}
// 4. Create EventBridge rule
rule, err := cloudwatch.NewEventRule(ctx, "daily-backup", &cloudwatch.EventRuleArgs{
Name: pulumi.String("daily-backup-trigger"),
ScheduleExpression: pulumi.String("cron(0 2 * * ? *)"), // 2 AM daily
})
if err != nil {
return err
}
ctx.Export("topicArn", topic.Arn)
ctx.Export("logGroup", logGroup.Name)
ctx.Export("ruleArn", rule.Arn)
return nil
})
}Deploy a complete Kubernetes cluster on AWS.
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/eks"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// 1. Create EKS cluster role
assumeRolePolicy, _ := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{{
"Effect": "Allow",
"Principal": map[string]string{"Service": "eks.amazonaws.com"},
"Action": "sts:AssumeRole",
}},
})
clusterRole, err := iam.NewRole(ctx, "eks-cluster-role", &iam.RoleArgs{
AssumeRolePolicy: pulumi.String(string(assumeRolePolicy)),
})
if err != nil {
return err
}
_, err = iam.NewRolePolicyAttachment(ctx, "eks-cluster-policy", &iam.RolePolicyAttachmentArgs{
Role: clusterRole.Name,
PolicyArn: pulumi.String("arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"),
})
if err != nil {
return err
}
// 2. Create EKS cluster
cluster, err := eks.NewCluster(ctx, "cluster", &eks.ClusterArgs{
Name: pulumi.String("my-cluster"),
Version: pulumi.String("1.30"),
RoleArn: clusterRole.Arn,
VpcConfig: &eks.ClusterVpcConfigArgs{
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-12345"),
pulumi.String("subnet-67890"),
},
},
}, pulumi.DependsOn([]pulumi.Resource{clusterRole}))
if err != nil {
return err
}
// 3. Create node group role
nodeAssumePolicy, _ := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{{
"Effect": "Allow",
"Principal": map[string]string{"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole",
}},
})
nodeRole, err := iam.NewRole(ctx, "node-role", &iam.RoleArgs{
AssumeRolePolicy: pulumi.String(string(nodeAssumePolicy)),
})
if err != nil {
return err
}
// Attach required policies
policies := []string{
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
}
for i, policyArn := range policies {
_, err = iam.NewRolePolicyAttachment(ctx, fmt.Sprintf("node-policy-%d", i), &iam.RolePolicyAttachmentArgs{
Role: nodeRole.Name,
PolicyArn: pulumi.String(policyArn),
})
if err != nil {
return err
}
}
// 4. Create node group
_, err = eks.NewNodeGroup(ctx, "node-group", &eks.NodeGroupArgs{
ClusterName: cluster.Name,
NodeRoleArn: nodeRole.Arn,
SubnetIds: pulumi.StringArray{
pulumi.String("subnet-12345"),
pulumi.String("subnet-67890"),
},
ScalingConfig: &eks.NodeGroupScalingConfigArgs{
DesiredSize: pulumi.Int(2),
MinSize: pulumi.Int(1),
MaxSize: pulumi.Int(4),
},
InstanceTypes: pulumi.StringArray{
pulumi.String("t3.medium"),
},
})
if err != nil {
return err
}
ctx.Export("clusterName", cluster.Name)
ctx.Export("clusterEndpoint", cluster.Endpoint)
return nil
})
}Secure secrets storage using Secrets Manager and KMS.
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/secretsmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// 1. Create KMS key
key, err := kms.NewKey(ctx, "secrets-key", &kms.KeyArgs{
Description: pulumi.String("Secrets encryption key"),
EnableKeyRotation: pulumi.Bool(true),
DeletionWindowInDays: pulumi.Int(10),
})
if err != nil {
return err
}
// 2. Create secret
secret, err := secretsmanager.NewSecret(ctx, "db-password", &secretsmanager.SecretArgs{
Name: pulumi.String("prod/db/password"),
Description: pulumi.String("Database password"),
KmsKeyId: key.Arn,
RecoveryWindowInDays: pulumi.Int(7),
})
if err != nil {
return err
}
// 3. Store secret value
credentials, _ := json.Marshal(map[string]string{
"username": "admin",
"password": "SecurePassword123!",
"host": "db.example.com",
"port": "5432",
})
_, err = secretsmanager.NewSecretVersion(ctx, "db-password-value", &secretsmanager.SecretVersionArgs{
SecretId: secret.ID(),
SecretString: pulumi.String(string(credentials)),
})
if err != nil {
return err
}
ctx.Export("secretArn", secret.Arn)
return nil
})
}For additional scenarios and patterns:
For detailed API specifications:
Install with Tessl CLI
npx tessl i tessl/golang-github-com-pulumi-pulumi-aws-sdk-v7@7.16.1docs