CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/golang-github-com-pulumi-pulumi-aws-sdk-v7

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.

Overview
Eval results
Files

real-world-scenarios.mddocs/examples/

Real-World Scenarios

Production-ready examples demonstrating complete infrastructure patterns using the Pulumi AWS Provider.

Scenario 1: Serverless API with Lambda and API Gateway {#lambda-api-gateway}

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
    })
}

Scenario 2: Static Website with S3, CloudFront, and Route53 {#static-website}

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
    })
}

Scenario 3: Container Service with ECS and ALB {#ecs-alb}

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
    })
}

Scenario 3: VPC with Multi-AZ Architecture

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
    })
}

Scenario 4: Lambda with DynamoDB Stream Processing

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
    })
}

Scenario 5: Multi-Region Deployment

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
    })
}

Scenario 6: Cross-Account Deployment

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
    })
}

Scenario 7: Secure Database Stack

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
    })
}

Scenario 8: Complete Monitoring Stack

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
    })
}

Scenario 9: EKS Cluster with Node Group

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
    })
}

Scenario 10: Secrets Management with KMS

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
    })
}

More Examples

For additional scenarios and patterns:

  • Edge Cases: Edge Cases and Troubleshooting
  • Compute Services: Compute Reference
  • Networking: Networking Reference
  • Database: Database Reference

Reference Documentation

For detailed API specifications:

Install with Tessl CLI

npx tessl i tessl/golang-github-com-pulumi-pulumi-aws-sdk-v7@7.16.1

docs

examples

edge-cases.md

real-world-scenarios.md

index.md

tile.json