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

quick-start.mddocs/guides/

Quick Start Guide - Pulumi AWS Provider

This guide will help you get started with the Pulumi AWS Provider for Go in minutes.

Prerequisites

  • Go 1.18 or later installed
  • AWS account with credentials configured
  • Pulumi CLI installed (curl -fsSL https://get.pulumi.com | sh)

Step 1: Install the SDK

go get github.com/pulumi/pulumi/sdk/v3/go/pulumi
go get github.com/pulumi/pulumi-aws/sdk/v7

Step 2: Configure AWS Credentials

Option A: Environment Variables

export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_REGION=us-east-1

Option B: AWS Profile

aws configure --profile myprofile
export AWS_PROFILE=myprofile

Option C: In Provider Code

provider, err := aws.NewProvider(ctx, "aws", &aws.ProviderArgs{
    Region:  pulumi.StringPtr("us-east-1"),
    Profile: pulumi.StringPtr("myprofile"),
})

Step 3: Create Your First Resource

Example 1: S3 Bucket

package main

import (
    "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 {
        // Create S3 bucket
        bucket, err := s3.NewBucketV2(ctx, "my-bucket", &s3.BucketV2Args{
            Bucket: pulumi.String("my-unique-bucket-name-12345"),
            Tags: pulumi.StringMap{
                "Environment": pulumi.String("dev"),
            },
        })
        if err != nil {
            return err
        }

        // Block public access
        _, 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
        }

        // Export bucket name
        ctx.Export("bucketName", bucket.Bucket)
        ctx.Export("bucketArn", bucket.Arn)
        return nil
    })
}

Run it:

pulumi up

Example 2: EC2 Instance

package main

import (
    "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 {
        // Lookup latest Amazon Linux 2 AMI
        ami, err := ec2.LookupAmi(ctx, &ec2.LookupAmiArgs{
            MostRecent: pulumi.BoolRef(true),
            Owners:     []string{"amazon"},
            Filters: []ec2.GetAmiFilter{
                {Name: "name", Values: []string{"amzn2-ami-hvm-*-x86_64-gp2"}},
            },
        }, nil)
        if err != nil {
            return err
        }

        // Create security group
        sg, err := ec2.NewSecurityGroup(ctx, "web-sg", &ec2.SecurityGroupArgs{
            Description: pulumi.String("Allow HTTP traffic"),
            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
        }

        // Create EC2 instance
        instance, err := ec2.NewInstance(ctx, "web-server", &ec2.InstanceArgs{
            Ami:                 pulumi.String(ami.Id),
            InstanceType:        pulumi.String("t3.micro"),
            VpcSecurityGroupIds: pulumi.StringArray{sg.ID()},
            Tags: pulumi.StringMap{
                "Name": pulumi.String("web-server"),
            },
        })
        if err != nil {
            return err
        }

        ctx.Export("instanceId", instance.ID())
        ctx.Export("publicIp", instance.PublicIp)
        return nil
    })
}

Example 3: Lambda Function

package main

import (
    "encoding/json"
    "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 {
        // Create IAM role for Lambda
        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
        }

        // Create Lambda function
        fn, err := lambda.NewFunction(ctx, "my-function", &lambda.FunctionArgs{
            Runtime: pulumi.String("python3.12"),
            Handler: pulumi.String("index.handler"),
            Role:    role.Arn,
            Code:    pulumi.NewFileArchive("./function"),
        }, pulumi.DependsOn([]pulumi.Resource{role}))
        if err != nil {
            return err
        }

        ctx.Export("functionName", fn.Name)
        ctx.Export("functionArn", fn.Arn)
        return nil
    })
}

Step 4: Common Operations

Deploy Infrastructure

pulumi up

Preview Changes

pulumi preview

Destroy Resources

pulumi destroy

View Outputs

pulumi stack output
pulumi stack output bucketName

View State

pulumi stack

Common Patterns

Pattern 1: Resource Dependencies

// Automatic dependency (via Output reference)
bucket, err := s3.NewBucketV2(ctx, "bucket", &s3.BucketV2Args{
    Bucket: pulumi.String("my-bucket"),
})
if err != nil {
    return err
}

policy, err := s3.NewBucketPolicy(ctx, "policy", &s3.BucketPolicyArgs{
    Bucket: bucket.ID(),  // Automatic dependency
    Policy: pulumi.String(policyJSON),
})

Pattern 2: Multi-Resource Setup

// VPC
vpc, err := ec2.NewVpc(ctx, "main", &ec2.VpcArgs{
    CidrBlock: pulumi.String("10.0.0.0/16"),
})
if err != nil {
    return err
}

// Subnet depends on VPC
subnet, err := ec2.NewSubnet(ctx, "subnet", &ec2.SubnetArgs{
    VpcId:     vpc.ID(),  // Automatic dependency
    CidrBlock: pulumi.String("10.0.1.0/24"),
})
if err != nil {
    return err
}

// Security group in VPC
sg, err := ec2.NewSecurityGroup(ctx, "sg", &ec2.SecurityGroupArgs{
    VpcId: vpc.ID(),  // Automatic dependency
})
if err != nil {
    return err
}

Pattern 3: Conditional Resources

var natGateway *ec2.NatGateway

if enableNAT {
    eip, err := ec2.NewEip(ctx, "nat-eip", &ec2.EipArgs{
        Domain: pulumi.String("vpc"),
    })
    if err != nil {
        return err
    }

    natGateway, err = ec2.NewNatGateway(ctx, "nat", &ec2.NatGatewayArgs{
        AllocationId: eip.AllocationId,
        SubnetId:     publicSubnet.ID(),
    })
    if err != nil {
        return err
    }
}

// Use natGateway if it was created
if natGateway != nil {
    // Configure private route table...
}

Pattern 4: Output Transformations

bucket, err := s3.NewBucketV2(ctx, "bucket", &s3.BucketV2Args{
    Bucket: pulumi.String("my-bucket"),
})
if err != nil {
    return err
}

// Transform bucket ARN to include /* suffix
bucketObjects := bucket.Arn.ApplyT(func(arn string) (string, error) {
    return fmt.Sprintf("%s/*", arn), nil
}).(pulumi.StringOutput)

// Use in policy
policyDoc := iam.GetPolicyDocumentOutput(ctx, iam.GetPolicyDocumentOutputArgs{
    Statements: iam.GetPolicyDocumentStatementArray{
        &iam.GetPolicyDocumentStatementArgs{
            Actions:   pulumi.StringArray{pulumi.String("s3:GetObject")},
            Resources: pulumi.StringArray{bucketObjects},
        },
    },
})

Troubleshooting

Issue: "No valid credential sources"

Solution: Configure AWS credentials via environment variables, profile, or provider args.

export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
export AWS_REGION=us-east-1

Issue: "Resource already exists"

Solution: Use pulumi.Import() to import existing resources.

bucket, err := s3.GetBucketV2(ctx, "existing", 
    pulumi.ID("existing-bucket-name"),
    &s3.BucketV2State{},
    pulumi.Import(pulumi.ID("existing-bucket-name")))

Issue: "DependencyViolation"

Solution: Add explicit dependency with pulumi.DependsOn().

resource, err := service.NewResource(ctx, "resource", &service.ResourceArgs{},
    pulumi.DependsOn([]pulumi.Resource{prerequisite}))

Next Steps

  • Learn more patterns: Real-World Scenarios
  • Handle edge cases: Edge Cases Guide
  • Explore specific services: Browse Reference Documentation
  • Configure provider: Provider Reference

Best Practices

  1. Always handle errors: Every AWS operation can fail
  2. Use Output types: For cross-resource dependencies
  3. Tag your resources: Use provider DefaultTags
  4. Enable IMDSv2: For EC2 security
  5. Use VPC endpoints: To reduce NAT gateway costs
  6. Enable encryption: KMS for data at rest
  7. Multi-AZ deployment: For high availability
  8. Monitor with CloudWatch: Set up alarms and logs

Ready to build? Start with the examples above or explore Real-World Scenarios for production patterns.

Install with Tessl CLI

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

docs

index.md

tile.json