2019-08-23 14:22:47 -07:00
|
|
|
---
|
2022-12-08 15:41:39 -08:00
|
|
|
title_tag: "Using AWS Identity & Access Management (IAM) | Crosswalk"
|
2023-05-15 15:25:28 -07:00
|
|
|
title: IAM
|
|
|
|
h1: AWS Identity & Access Management (IAM)
|
2019-12-18 09:59:20 -08:00
|
|
|
meta_desc: Pulumi Crosswalk for AWS adds strongly typed IAM resource classes, for creating, updating, and
|
|
|
|
otherwise managing AWS users, groups, and roles securely.
|
2023-06-08 16:15:52 -07:00
|
|
|
meta_image: /images/docs/meta-images/docs-clouds-aws-meta-image.png
|
2019-08-23 14:22:47 -07:00
|
|
|
menu:
|
2023-05-15 15:25:28 -07:00
|
|
|
clouds:
|
|
|
|
parent: aws-guides
|
|
|
|
identifier: aws-guides-iam
|
2019-08-23 14:22:47 -07:00
|
|
|
weight: 8
|
2023-05-15 15:25:28 -07:00
|
|
|
aliases:
|
|
|
|
- /docs/reference/crosswalk/aws/iam/
|
|
|
|
- /docs/guides/crosswalk/aws/iam/
|
2019-08-23 14:22:47 -07:00
|
|
|
---
|
|
|
|
|
2022-10-26 07:22:15 -07:00
|
|
|
<a href="./">
|
2019-08-23 14:22:47 -07:00
|
|
|
<img src="/images/docs/reference/crosswalk/aws/logo.svg" align="right" width="280" style="margin: 0 0 32px 16px;">
|
|
|
|
</a>
|
|
|
|
|
|
|
|
[AWS Identity and Access Management (IAM)](https://aws.amazon.com/iam/) enables you to manage access to AWS services
|
|
|
|
and resources securely. Using IAM, you can create and manage AWS users and groups, and use permissions to allow and
|
|
|
|
deny their access to AWS resources.
|
|
|
|
|
2022-05-03 23:47:05 +01:00
|
|
|
{{% notes type="info" %}}
|
2022-10-26 07:22:15 -07:00
|
|
|
This functionality is available in TypeScript only and as part of the [AWS Classic provider](/registry/packages/aws/).
|
2022-05-03 23:47:05 +01:00
|
|
|
{{% /notes %}}
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
## Overview
|
|
|
|
|
|
|
|
Pulumi Crosswalk for AWS adds strongly typed IAM resource classes, to ensure that you can create, update, and
|
|
|
|
otherwise manage AWS users, groups, and roles securely and robustly.
|
|
|
|
|
|
|
|
## Creating IAM Policy Documents Safely and Easily
|
|
|
|
|
|
|
|
You manage access in AWS by creating policies and attaching them to IAM identities or AWS resources. A policy is an
|
|
|
|
object in AWS that, when associated with an entity or resource, defines their permissions. AWS evaluates these
|
|
|
|
policies when a principal, such as a user, makes a request. Permissions in the policies determine whether the request
|
|
|
|
is allowed or denied.
|
|
|
|
|
|
|
|
### Policy Documents
|
|
|
|
|
|
|
|
IAM policies define permissions for an action regardless of the method that you use to perform the operation. For
|
|
|
|
example, if a policy allows the GetUser action, then a user with that policy can get user information from the AWS
|
|
|
|
Management Console, the AWS CLI, or the AWS API. When you create an IAM user, you can set up the user to allow console
|
|
|
|
or programmatic access. The IAM user can sign in to the console using a user name and password. Or they can use
|
|
|
|
access keys to work with the CLI or API.
|
|
|
|
|
|
|
|
Most policies are stored in AWS as JSON documents. Identity-based policies, policies used to set boundaries, or AWS
|
|
|
|
STS boundary policies are JSON policy documents that you attach to a user or role. Resource-based policies are JSON
|
|
|
|
policy documents that you attach to a resource. SCPs are JSON policy documents with restricted syntax that you attach
|
|
|
|
to an AWS Organizations organizational unit (OU). ACLs are also attached to a resource, but you use a different syntax.
|
|
|
|
|
|
|
|
A JSON policy document includes these elements:
|
|
|
|
|
|
|
|
* Optional policywide information at the top of the document
|
|
|
|
* One or more individual statements
|
|
|
|
|
|
|
|
Each statement includes information about a single permission. If a policy includes multiple statements, AWS applies
|
|
|
|
a logical OR across the statements when evaluating them. If multiple policies apply to a request, AWS applies a logical
|
|
|
|
OR across all of those policies when evaluating them.
|
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For more extensive details about IAM policies and their contents, refer to the [AWS access policies documentation](
|
2019-08-23 14:22:47 -07:00
|
|
|
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html).
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
#### Strongly Typed Policy Documents (TypeScript-only)
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
Pulumi Crosswalk for AWS in TypeScript defines [the `aws.iam.PolicyDocument` interface](
|
2022-10-26 07:22:15 -07:00
|
|
|
/registry/packages/aws/api-docs/iam) to add strong type checking to your policy documents. By using
|
2019-08-23 14:22:47 -07:00
|
|
|
this type, we will know at compile time whether we've mistyped an attribute:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
import * as aws from "@pulumi/aws";
|
|
|
|
|
|
|
|
const policy: aws.iam.PolicyDocument = {
|
|
|
|
Version: "2012-10-17",
|
|
|
|
Statement: [
|
|
|
|
{
|
|
|
|
Action: "sts:AssumeRole",
|
|
|
|
Principal: {
|
|
|
|
Service: "ec2.amazonaws.com"
|
|
|
|
},
|
|
|
|
Effect: "Allow",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
This policy object can then be used to configure a variety of IAM objects, as we will see below. For example, we can
|
|
|
|
use the above policy to configure an IAM role that permits an assume role action for a given principal:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
const role = new aws.iam.Role("instance-role", {
|
|
|
|
assumeRolePolicy: policy,
|
|
|
|
path: "/",
|
|
|
|
});
|
|
|
|
const profile = new aws.iam.InstanceProfile("instance-profile", { role });
|
|
|
|
```
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
### Pre-Defined IAM Managed Policies
|
2019-08-23 14:22:47 -07:00
|
|
|
|
|
|
|
An AWS managed policy is a standalone policy that is created and administered by AWS. Standalone policy means that
|
|
|
|
the policy has its own Amazon Resource Name (ARN) that includes the policy name. For example,
|
2021-11-16 14:20:55 -08:00
|
|
|
`arn:aws:iam::aws:policy/IAMReadOnlyAccess` is an AWS managed policy.
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
In places that accept a policy ARN, such as the `RolePolicyAttachment` resource, you can pass the ARN as a string,
|
|
|
|
but that requires that you either memorize or look up the ARN each time. Instead, you can use the strongly typed
|
|
|
|
`ManagedPolicy` enum, which exports a collection of constants for all available managed policies.
|
|
|
|
|
|
|
|
For example, instead of typing out the ARN by hand, we can just reference `ManagedPolicy`'s `IAMReadOnlyAccess`
|
|
|
|
enum value:
|
|
|
|
|
|
|
|
{{< chooser language "typescript,python,go,csharp" / >}}
|
|
|
|
|
|
|
|
{{% choosable language "javascript,typescript" %}}
|
2019-08-23 14:22:47 -07:00
|
|
|
|
|
|
|
```typescript
|
|
|
|
const role = ...;
|
|
|
|
const rolePolicyAttachment = new aws.iam.RolePolicyAttachment("rpa", {
|
|
|
|
role: role,
|
2021-11-16 14:20:55 -08:00
|
|
|
policyArn: aws.iam.ManagedPolicy.IAMReadOnlyAccess,
|
2019-08-23 14:22:47 -07:00
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language python %}}
|
|
|
|
|
|
|
|
```python
|
|
|
|
role = ...
|
|
|
|
role_policy_attachment = aws.iam.RolePolicyAttachment('rpa',
|
|
|
|
role=role,
|
|
|
|
policy_arn=aws.iam.ManagedPolicy.IAMReadOnlyAccess,
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language go %}}
|
|
|
|
|
|
|
|
```go
|
|
|
|
role := ...
|
|
|
|
rolePolicyAttachment, err := iam.NewRolePolicyAttachment("rpa", &iam.RolePolicyAttachmentArgs{}
|
|
|
|
Role: role,
|
|
|
|
PolicyArn: iam.ManagedPolicyIAMReadOnlyAccess,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language csharp %}}
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
var role = ...;
|
|
|
|
var rolePolicyAttachment = new Iam.RolePolicyAttachment("rpa", new Iam.RolePolicyAttachmentArgs
|
|
|
|
{
|
|
|
|
Role = role,
|
|
|
|
PolicyArn = Iam.ManagedPolicy.IAMReadOnlyAccess.ToString(),
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For a full list of available managed policy ARNs, refer to the
|
2022-10-26 07:22:15 -07:00
|
|
|
[API documentation](/registry/packages/aws/api-docs/iam/).
|
2019-08-23 14:22:47 -07:00
|
|
|
|
|
|
|
## Creating IAM Users, Groups, and Roles
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
The primary IAM object types are users, groups, and roles. This section demonstrates how they
|
|
|
|
relate and how to create and configure them.
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
### IAM Users
|
|
|
|
|
|
|
|
An AWS Identity and Access Management (IAM) user is an entity that you create in AWS to represent the person or
|
|
|
|
application that uses it to interact with AWS. A user in AWS consists of a name and credentials.
|
|
|
|
|
2022-10-26 07:22:15 -07:00
|
|
|
Use the [`User` resource](/registry/packages/aws/api-docs/iam/user) to create new
|
2019-08-23 14:22:47 -07:00
|
|
|
IAM users. This example creates an IAM user and attaches a policy:
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{< chooser language "typescript,python,go,csharp" / >}}
|
|
|
|
|
|
|
|
{{% choosable language "javascript,typescript" %}}
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
```typescript
|
|
|
|
import * as aws from "@pulumi/aws";
|
|
|
|
|
|
|
|
const user = new aws.iam.User("webmaster", {
|
|
|
|
path: "/system/",
|
|
|
|
tags: { "Name": "webmaster" },
|
|
|
|
});
|
2020-01-13 22:29:33 -08:00
|
|
|
const userAccessKey = new aws.iam.AccessKey("webmasterKey", { user: user.name });
|
2019-08-23 14:22:47 -07:00
|
|
|
const userPolicy = new aws.iam.UserPolicy("webmasterPolicy", {
|
|
|
|
user,
|
|
|
|
policy: {
|
|
|
|
Version: "2012-10-17",
|
|
|
|
Statement: [{
|
|
|
|
Action: [ "ec2:Describe*" ],
|
|
|
|
Effect: "Allow",
|
|
|
|
Resource: "*",
|
|
|
|
}],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language python %}}
|
|
|
|
|
|
|
|
```python
|
|
|
|
import json
|
|
|
|
import pulumi_aws as aws
|
|
|
|
|
|
|
|
user = aws.iam.User('webmaster',
|
|
|
|
path='/system/',
|
|
|
|
tags={ 'Name': 'webmaster' },
|
|
|
|
)
|
|
|
|
user_access_key = aws.iam.AccessKey('webmasterKey',
|
|
|
|
user=user.name,
|
|
|
|
)
|
|
|
|
user_policy = aws.iam.UserPolicy('webmasterPolicy',
|
|
|
|
user=user.id,
|
|
|
|
policy=json.dumps({
|
|
|
|
'Version': '2012-10-17',
|
|
|
|
'Statement': [{
|
|
|
|
'Action': [ 'ec2:Describe*' ],
|
|
|
|
'Effect': 'Allow',
|
|
|
|
'Resource': '*'
|
|
|
|
}],
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language go %}}
|
|
|
|
|
|
|
|
```go
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/iam"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
pulumi.Run(func(ctx *pulumi.Context) error {
|
|
|
|
user, err := iam.NewUser(ctx, "webmaster", &iam.UserArgs{
|
|
|
|
Path: pulumi.String("/system/"),
|
|
|
|
Tags: pulumi.StringMap{
|
|
|
|
"Name": pulumi.String("webmaster"),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
userAccessKey, err := iam.NewAccessKey(ctx, "webmasterKey", &iam.AccessKeyArgs{
|
|
|
|
User: user.Name,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
userPolicy, err := iam.NewUserPolicy(ctx, "webmasterPolicy", &iam.UserPolicyArgs{
|
|
|
|
User: user.ID().ToStringOutput(),
|
|
|
|
Policy: pulumi.String(`{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [{
|
|
|
|
"Action": [ "ec2:Describe*" ],
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Resource": "*"
|
|
|
|
}]
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Export("userId", user.ID())
|
|
|
|
ctx.Export("userAccessKeyId", userAccessKey.ID())
|
|
|
|
ctx.Export("userPolicyId", userPolicy.ID())
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language csharp %}}
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
using Pulumi;
|
|
|
|
using Iam = Pulumi.Aws.Iam;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
|
|
|
class MyStack : Stack
|
|
|
|
{
|
|
|
|
public MyStack()
|
|
|
|
{
|
|
|
|
var user = new Iam.User("webmaster", new Iam.UserArgs
|
|
|
|
{
|
|
|
|
Path = "/system",
|
|
|
|
Tags = new Dictionary<string, string>
|
|
|
|
{
|
|
|
|
{ "Name", "webmaster" },
|
|
|
|
}.ToImmutableDictionary(),
|
|
|
|
});
|
|
|
|
var userAccessKey = new Iam.AccessKey("webmasterKey", new Iam.AccessKeyArgs
|
|
|
|
{
|
|
|
|
User = user.Name,
|
|
|
|
});
|
|
|
|
var userPolicy = new Iam.UserPolicy("webmasterPolicy", new Iam.UserPolicyArgs
|
|
|
|
{
|
|
|
|
User = user.Name,
|
|
|
|
Policy = @"{
|
|
|
|
""Version"": ""2012-10-17"",
|
|
|
|
""Statement"": [{
|
|
|
|
""Action"": [ ""ec2:Describe*"" ],
|
|
|
|
""Effect"": ""Allow"",
|
|
|
|
""Resource"": ""*""
|
|
|
|
}]
|
|
|
|
}
|
|
|
|
",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For more options available when configuring IAM users, see the [API documentation](
|
2022-10-26 07:22:15 -07:00
|
|
|
/registry/packages/aws/api-docs/iam/user).
|
2019-08-23 14:22:47 -07:00
|
|
|
|
|
|
|
If you'd like to configure non-service account users that can login to the
|
2022-10-26 07:22:15 -07:00
|
|
|
AWS console, see [`UserLoginProfile`](/registry/packages/aws/api-docs/iam/userloginprofile),
|
|
|
|
and for creating access keys, see [`AccessKey`](/registry/packages/aws/api-docs/iam/accesskey).
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2020-04-17 11:53:52 -07:00
|
|
|
If you need to attach a managed policy ARN to your user, use the [`UserPolicyAttachment` resource](
|
2022-10-26 07:22:15 -07:00
|
|
|
/registry/packages/aws/api-docs/iam/userpolicyattachment).
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
Finally, for detailed information about IAM Users, refer to the [AWS documentation](
|
2019-08-23 14:22:47 -07:00
|
|
|
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html).
|
|
|
|
|
|
|
|
### IAM Groups
|
|
|
|
|
|
|
|
An IAM group is a collection of IAM users, making it easier for you specify permissions for multiple users at once.
|
|
|
|
For example, you could have a group called Admins and give that group the types of permissions that administrators need.
|
|
|
|
Any user in that group automatically has the permissions assigned to the group. If a new user joins your organization
|
|
|
|
and needs administrator privileges, you can assign the appropriate permissions by adding the user to that group.
|
|
|
|
Similarly, if a person changes jobs in your organization, instead of editing that user's permissions, you can remove
|
|
|
|
them from the old groups and add them to the appropriate new groups.
|
|
|
|
|
2022-10-26 07:22:15 -07:00
|
|
|
Use the [`Group` resource](/registry/packages/aws/api-docs/iam/group) to manage
|
2019-08-23 14:22:47 -07:00
|
|
|
IAM groups. For example, this code creates a new group for an organization's developers, specifies a policy for that
|
|
|
|
group, and adds a couple users into it, thereby granting them permissions from the developer group all at once:
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{< chooser language "typescript,python,go,csharp" / >}}
|
|
|
|
|
|
|
|
{{% choosable language "javascript,typescript" %}}
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
```typescript
|
|
|
|
import * as aws from "@pulumi/aws";
|
|
|
|
|
|
|
|
// Create our users.
|
|
|
|
const jane = new aws.iam.User("jane", ...);
|
|
|
|
const mary = new aws.iam.User("mary", ...);
|
|
|
|
|
|
|
|
// Define a group and assign a policy for it.
|
|
|
|
const devs = new aws.iam.Group("devs", {
|
|
|
|
path: "/users/",
|
|
|
|
});
|
|
|
|
const myDeveloperPolicy = new aws.iam.GroupPolicy("my_developer_policy", {
|
2021-11-19 20:02:22 +01:00
|
|
|
group: devs.id,
|
2019-08-23 14:22:47 -07:00
|
|
|
policy: {
|
|
|
|
Version: "2012-10-17",
|
|
|
|
Statement: [{
|
|
|
|
Action: [ "ec2:Describe*" ],
|
|
|
|
Effect: "Allow",
|
|
|
|
Resource: "*",
|
|
|
|
}],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
// Finally add the users as members to this group.
|
|
|
|
const devTeam = new aws.iam.GroupMembership("dev-team", {
|
2021-11-19 20:02:22 +01:00
|
|
|
group: devs.id,
|
|
|
|
users: [ jane.id, mary.id ],
|
2019-08-23 14:22:47 -07:00
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language python %}}
|
|
|
|
|
|
|
|
```python
|
|
|
|
import json
|
|
|
|
import pulumi_aws as aws
|
|
|
|
|
|
|
|
# Create our users.
|
|
|
|
jane = aws.iam.User('jane', ...)
|
|
|
|
mary = aws.iam.User('mary', ...)
|
|
|
|
|
|
|
|
# Define a group and assign a policy for it.
|
|
|
|
devs = aws.iam.Group('devs',
|
|
|
|
path='/users/',
|
|
|
|
)
|
|
|
|
my_developer_policy = aws.iam.GroupPolicy('my_developer_policy',
|
|
|
|
group=devs.id,
|
|
|
|
policy=json.dumps({
|
|
|
|
'Version': '2012-10-17',
|
|
|
|
'Statement': [{
|
|
|
|
'Action': [ 'ec2:Describe*' ],
|
|
|
|
'Effect': 'Allow',
|
|
|
|
'Resource': '*',
|
|
|
|
}],
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
|
|
|
|
# Finally add the users as members to this group.
|
|
|
|
dev_team = aws.iam.GroupMembership('dev-team',
|
|
|
|
group=devs.id,
|
|
|
|
users=[ jane.id, mary.id ],
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language go %}}
|
|
|
|
|
|
|
|
```go
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/iam"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
pulumi.Run(func(ctx *pulumi.Context) error {
|
|
|
|
// Create our users.
|
|
|
|
jane, err := iam.NewUser(ctx, "jane", &iam.UserArgs{...})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
mary, err := iam.NewUser(ctx, "mary", &iam.UserArgs{...})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Define a group and assign a policy for it.
|
|
|
|
devs, err := iam.NewGroup(ctx, "devs", &iam.GroupArgs{
|
|
|
|
Path: pulumi.String("/users/"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
myDeveloperPolicy, err := iam.NewGroupPolicy(
|
|
|
|
ctx, "my_developer_policy", &iam.GroupPolicyArgs{
|
|
|
|
Group: devs.ID().ToStringOutput(),
|
|
|
|
Policy: pulumi.String(`{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [{
|
|
|
|
"Action": [ "ec2:Describe*" ],
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Resource": "*"
|
|
|
|
}]
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally add the users as members to this group.
|
|
|
|
devTeam, err := iam.NewGroupMembership(
|
|
|
|
ctx, "dev-team", &iam.GroupMembershipArgs{
|
|
|
|
Group: devs.ID().ToStringOutput(),
|
|
|
|
Users: pulumi.StringArray{
|
|
|
|
jane.ID().ToStringOutput(),
|
|
|
|
mary.ID().ToStringOutput(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Export("devsGroupId", devs.ID())
|
|
|
|
ctx.Export("devsGroupPolicyId", myDeveloperPolicy.ID())
|
|
|
|
ctx.Export("devsGroupMembershipId", devTeam.ID())
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language csharp %}}
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
using Pulumi;
|
|
|
|
using Iam = Pulumi.Aws.Iam;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
|
|
|
class MyStack : Stack
|
|
|
|
{
|
|
|
|
public MyStack()
|
|
|
|
{
|
|
|
|
// Create our users.
|
|
|
|
var jane = new Iam.User("jane", new Iam.UserArgs{});
|
|
|
|
var mary = new Iam.User("mary", new Iam.UserArgs{});
|
|
|
|
|
|
|
|
// Define a group and assign a policy for it.
|
|
|
|
var devs = new Iam.Group("devs", new Iam.GroupArgs
|
|
|
|
{
|
|
|
|
Path = "/users/",
|
|
|
|
});
|
|
|
|
var myDeveloperPolicy = new Iam.GroupPolicy("my_developer_policy", new Iam.GroupPolicyArgs
|
|
|
|
{
|
|
|
|
Group = devs.Id,
|
|
|
|
Policy = @"{
|
|
|
|
""Version"": ""2012-10-17"",
|
|
|
|
""Statement"": [{
|
|
|
|
""Action"": [ ""ec2:Describe*"" ],
|
|
|
|
""Effect"": ""Allow"",
|
|
|
|
""Resource"": ""*""
|
|
|
|
}]
|
|
|
|
}
|
|
|
|
",
|
|
|
|
});
|
|
|
|
|
|
|
|
// Finally add the users as members to this group.
|
|
|
|
var devTeam = new Iam.GroupMembership("dev-team", new Iam.GroupMembershipArgs
|
|
|
|
{
|
|
|
|
Group = devs.Id,
|
|
|
|
Users = { jane.Id, mary.Id },
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For more information, refer to the API documentation for [groups](
|
2022-10-26 07:22:15 -07:00
|
|
|
/registry/packages/aws/api-docs/iam/group), [group membership](
|
|
|
|
/registry/packages/aws/api-docs/iam/groupmembership), and [group policies](
|
|
|
|
/registry/packages/aws/api-docs/iam/grouppolicy). If you need to attach a managed policy ARN to your group, use the
|
|
|
|
[`GroupPolicyAttachment` resource](/registry/packages/aws/api-docs/iam/grouppolicyattachment).
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
Finally, for detailed information about IAM Groups, refer to the
|
2019-08-23 14:22:47 -07:00
|
|
|
[AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html).
|
|
|
|
|
|
|
|
### IAM Roles
|
|
|
|
|
|
|
|
An IAM role is an IAM identity that you can create in your account that has specific permissions. This is similar to
|
|
|
|
an IAM user, in that it is an AWS identity with permission policies that determine what the identity can and cannot do
|
|
|
|
in AWS. Instead of being uniquely associated with one person, however, a role is assumable by anyone who needs it. Also,
|
|
|
|
a role does not have standard long-term credentials such as a password or access keys associated with it. Instead, when
|
|
|
|
you assume a role, it provides you with temporary security credentials for your role session.
|
|
|
|
|
2022-10-26 07:22:15 -07:00
|
|
|
To manage IAM roles, use the [`Role` resource](/registry/packages/aws/api-docs/iam/role).
|
2019-08-23 14:22:47 -07:00
|
|
|
The following example creates a new role with a custom policy document, and also attaches a managed policy afterwards:
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{< chooser language "typescript,python,go,csharp" / >}}
|
|
|
|
|
|
|
|
{{% choosable language "javascript,typescript" %}}
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
```typescript
|
|
|
|
import * as aws from "@pulumi/aws";
|
|
|
|
|
|
|
|
const role = new aws.iam.Role("my-role", {
|
|
|
|
assumeRolePolicy: {
|
|
|
|
Version: "2012-10-17",
|
|
|
|
Statement: [{
|
|
|
|
Action: "sts:AssumeRole",
|
|
|
|
Principal: {
|
|
|
|
Service: "ec2.amazonaws.com"
|
|
|
|
},
|
|
|
|
Effect: "Allow",
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const rolePolicyAttachment = new aws.iam.RolePolicyAttachment("my-rpa", {
|
|
|
|
role: role,
|
|
|
|
policyArn: aws.iam.IAMReadOnlyAccess,
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language python %}}
|
|
|
|
|
|
|
|
```python
|
|
|
|
import json
|
|
|
|
import pulumi_aws as aws
|
|
|
|
|
|
|
|
role = aws.iam.Role('my-role',
|
|
|
|
assume_role_policy=json.dumps({
|
|
|
|
'Version': '2012-10-17',
|
|
|
|
'Statement': [{
|
|
|
|
'Action': 'sts:AssumeRole',
|
|
|
|
'Principal': {
|
|
|
|
'Service': 'ec2.amazonaws.com'
|
|
|
|
},
|
|
|
|
'Effect': 'Allow',
|
|
|
|
}],
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
role_policy_attachment = aws.iam.RolePolicyAttachment('my-rpa',
|
|
|
|
role=role.id,
|
|
|
|
policy_arn='arn:aws:iam::aws:policy/ReadOnlyAccess',
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language go %}}
|
|
|
|
|
|
|
|
```go
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/iam"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
pulumi.Run(func(ctx *pulumi.Context) error {
|
|
|
|
role, err := iam.NewRole(ctx, "my-role", &iam.RoleArgs{
|
|
|
|
AssumeRolePolicy: pulumi.String(`{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [{
|
|
|
|
"Action": [ "sts:AssumeRole" ],
|
|
|
|
"Principal": {
|
|
|
|
"Service": "ec2.amazonaws.com"
|
|
|
|
},
|
2023-08-04 02:24:05 +09:00
|
|
|
"Effect": "Allow"
|
2021-11-16 14:20:55 -08:00
|
|
|
}]
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = iam.NewRolePolicyAttachment(
|
|
|
|
ctx, "my-rpa", &iam.RolePolicyAttachmentArgs{
|
|
|
|
Role: role.ID().ToStringOutput(),
|
|
|
|
PolicyArn: pulumi.String("arn:aws:iam::aws:policy/ReadOnlyAccess"),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language csharp %}}
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
using Pulumi;
|
|
|
|
using Iam = Pulumi.Aws.Iam;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
|
|
|
class MyStack : Stack
|
|
|
|
{
|
|
|
|
public MyStack()
|
|
|
|
{
|
|
|
|
var role = new Iam.Role("my-role", new Iam.RoleArgs
|
|
|
|
{
|
|
|
|
AssumeRolePolicy = @"{
|
|
|
|
""Version"": ""2012-10-17"",
|
|
|
|
""Statement"": [{
|
|
|
|
""Action"": [ ""sts:AssumeRole"" ],
|
|
|
|
""Principal"": {
|
|
|
|
""Service"": ""ec2.amazonaws.com""
|
|
|
|
},
|
2023-08-04 02:24:05 +09:00
|
|
|
""Effect"": ""Allow""
|
2021-11-16 14:20:55 -08:00
|
|
|
}]
|
|
|
|
}
|
|
|
|
",
|
|
|
|
});
|
|
|
|
var rolePolicyAttachment = new Iam.RolePolicyAttachment("my-rpa",
|
|
|
|
new Iam.RolePolicyAttachmentArgs
|
|
|
|
{
|
|
|
|
Role = role.Id,
|
|
|
|
PolicyArn = "arn:aws:iam::aws:policy/ReadOnlyAccess",
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
Roles are often useful for creating [instance profiles](
|
|
|
|
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html), which
|
|
|
|
controls the IAM role assumed by compute running inside of your AWS account, whether that be in EC2, ECS, EKS, or
|
2020-04-17 11:53:52 -07:00
|
|
|
Lambda, for example. To create one, use the [`InstanceProfile` resource](
|
2022-10-26 07:22:15 -07:00
|
|
|
/registry/packages/aws/api-docs/iam/instanceprofile) and pass in your role:
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{< chooser language "typescript,python,go,csharp" / >}}
|
|
|
|
|
|
|
|
{{% choosable language "javascript,typescript" %}}
|
|
|
|
|
2019-08-23 14:22:47 -07:00
|
|
|
```typescript
|
|
|
|
const profile = new aws.iam.InstanceProfile("instance-profile", { role });
|
|
|
|
```
|
|
|
|
|
2021-11-16 14:20:55 -08:00
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language python %}}
|
|
|
|
|
|
|
|
```python
|
|
|
|
profile = aws.iam.InstanceProfile('instance-profile', role=role.id)
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language go %}}
|
|
|
|
|
|
|
|
```go
|
|
|
|
profile, err := aws.iam.NewInstanceProfile(
|
|
|
|
ctx, "instance-profile", &aws.iam.InstanceProfileArgs{
|
|
|
|
Role: role.ID().ToStringOutput(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
|
|
|
{{% choosable language csharp %}}
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
var profile = new Iam.InstanceProfile("instance-profile", { Role = role.Id });
|
|
|
|
```
|
|
|
|
|
|
|
|
{{% /choosable %}}
|
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For specific information about configuring roles, refer to [the API documentation](
|
2022-10-26 07:22:15 -07:00
|
|
|
/registry/packages/aws/api-docs/iam/role). For more general information about IAM Roles, refer to the
|
2019-08-23 14:22:47 -07:00
|
|
|
[AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html).
|
|
|
|
|
|
|
|
## Additional IAM Resources
|
|
|
|
|
2020-11-16 07:11:05 -08:00
|
|
|
For more information about AWS IAM, see the following:
|
2019-08-23 14:22:47 -07:00
|
|
|
|
2022-10-26 07:22:15 -07:00
|
|
|
* [Pulumi AWS IAM API Documentation](/registry/packages/aws/api-docs/iam/)
|
2019-08-23 14:22:47 -07:00
|
|
|
* [Amazon Identity and Access Management (IAM) homepage](https://aws.amazon.com/iam/)
|