CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pulumi--aws

A Pulumi package for creating and managing Amazon Web Services (AWS) cloud resources with infrastructure-as-code.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

iam.mddocs/guides/

IAM Best Practices Guide

Guide for implementing AWS Identity and Access Management (IAM) best practices in your Pulumi infrastructure code.

Core Principles

Least Privilege Access

Grant only the permissions required to perform a task.

const role = new aws.iam.Role("app-role", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Action: "sts:AssumeRole",
            Effect: "Allow",
            Principal: {
                Service: "lambda.amazonaws.com",
            },
        }],
    }),
});

new aws.iam.RolePolicy("specific-permissions", {
    role: role.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Action: [
                "s3:GetObject",
                "s3:PutObject",
            ],
            Resource: `${bucket.arn}/*`,
        }],
    }),
});

Use IAM Roles Instead of Access Keys

For AWS services and EC2 instances, use IAM roles rather than embedding credentials.

const instanceRole = new aws.iam.Role("instance-role", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Action: "sts:AssumeRole",
            Effect: "Allow",
            Principal: {
                Service: "ec2.amazonaws.com",
            },
        }],
    }),
});

const instanceProfile = new aws.iam.InstanceProfile("instance-profile", {
    role: instanceRole.name,
});

const instance = new aws.ec2.Instance("web-server", {
    instanceType: "t3.micro",
    ami: "ami-12345678",
    iamInstanceProfile: instanceProfile.name,
});

Common Patterns

Service-Linked Roles

Create service-specific roles with managed policies.

const lambdaRole = new aws.iam.Role("lambda-role", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Action: "sts:AssumeRole",
            Effect: "Allow",
            Principal: {
                Service: "lambda.amazonaws.com",
            },
        }],
    }),
});

new aws.iam.RolePolicyAttachment("lambda-basic", {
    role: lambdaRole.name,
    policyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
});

Cross-Account Access

Enable secure access across AWS accounts.

const crossAccountRole = new aws.iam.Role("cross-account", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Action: "sts:AssumeRole",
            Effect: "Allow",
            Principal: {
                AWS: `arn:aws:iam::${trustedAccountId}:root`,
            },
            Condition: {
                StringEquals: {
                    "sts:ExternalId": externalId,
                },
            },
        }],
    }),
});

Policy Conditions

Use conditions for fine-grained access control.

const policy = new aws.iam.Policy("conditional-policy", {
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Action: "s3:*",
            Resource: "*",
            Condition: {
                IpAddress: {
                    "aws:SourceIp": ["10.0.0.0/16"],
                },
                StringEquals: {
                    "aws:RequestedRegion": ["us-west-2", "us-east-1"],
                },
            },
        }],
    }),
});

Resource-Based Policies

Attach policies directly to resources.

new aws.s3.BucketPolicy("bucket-policy", {
    bucket: bucket.id,
    policy: pulumi.all([bucket.arn, role.arn]).apply(([bucketArn, roleArn]) =>
        JSON.stringify({
            Version: "2012-10-17",
            Statement: [{
                Effect: "Allow",
                Principal: {
                    AWS: roleArn,
                },
                Action: ["s3:GetObject"],
                Resource: `${bucketArn}/*`,
            }],
        })
    ),
});

Security Best Practices

Enable MFA for Privileged Operations

const policy = new aws.iam.Policy("mfa-required", {
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Deny",
            Action: "*",
            Resource: "*",
            Condition: {
                BoolIfExists: {
                    "aws:MultiFactorAuthPresent": "false",
                },
            },
        }],
    }),
});

Rotate Credentials Regularly

Implement automatic credential rotation using Secrets Manager.

const secret = new aws.secretsmanager.Secret("db-credentials", {
    name: "database-credentials",
});

const rotation = new aws.secretsmanager.SecretRotation("rotation", {
    secretId: secret.id,
    rotationLambdaArn: rotationLambda.arn,
    rotationRules: {
        automaticallyAfterDays: 30,
    },
});

Use Permission Boundaries

Limit the maximum permissions a role can have.

const boundary = new aws.iam.Policy("boundary", {
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Action: [
                "s3:*",
                "dynamodb:*",
            ],
            Resource: "*",
        }],
    }),
});

const role = new aws.iam.Role("bounded-role", {
    assumeRolePolicy: "...",
    permissionsBoundary: boundary.arn,
});

Auditing and Monitoring

Enable CloudTrail

const trail = new aws.cloudtrail.Trail("audit-trail", {
    s3BucketName: auditBucket.id,
    includeGlobalServiceEvents: true,
    isMultiRegionTrail: true,
    enableLogFileValidation: true,
});

Monitor IAM Activity

const alarm = new aws.cloudwatch.MetricAlarm("unauthorized-api-calls", {
    name: "unauthorized-api-calls",
    metricName: "UnauthorizedAPICalls",
    namespace: "CloudTrailMetrics",
    statistic: "Sum",
    period: 300,
    evaluationPeriods: 1,
    threshold: 1,
    comparisonOperator: "GreaterThanOrEqualToThreshold",
    alarmActions: [snsTopic.arn],
});

Related Documentation

  • IAM Service Reference
  • Security Best Practices
  • Multi-Account Setup

Install with Tessl CLI

npx tessl i tessl/npm-pulumi--aws

docs

index.md

quickstart.md

README.md

tile.json