forked from serverless-components/aws-iam-role
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserverless.js
More file actions
125 lines (103 loc) · 3.49 KB
/
serverless.js
File metadata and controls
125 lines (103 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const { equals, mergeDeepRight } = require('ramda')
const aws = require('aws-sdk')
const {
createRole,
deleteRole,
getRole,
addRolePolicy,
removeRolePolicy,
updateAssumeRolePolicy,
inputsChanged
} = require('./utils')
const { Component, utils } = require('@serverless/core')
const defaults = {
service: 'lambda.amazonaws.com',
policy: {
arn: 'arn:aws:iam::aws:policy/AdministratorAccess'
},
region: 'us-east-1'
}
class AwsIamRole extends Component {
async default(inputs = {}) {
inputs = mergeDeepRight(defaults, inputs)
const iam = new aws.IAM({ region: inputs.region, credentials: this.context.credentials.aws })
this.context.status(`Deploying`)
inputs.name = this.state.name || this.context.resourceId()
this.context.debug(`Syncing role ${inputs.name} in region ${inputs.region}.`)
const prevRole = await getRole({ iam, ...inputs })
// If an inline policy, remove ARN
if (inputs.policy.Version && inputs.policy.Statement) {
if (inputs.policy.arn) {
delete inputs.policy.arn
}
}
if (!prevRole) {
this.context.debug(`Creating role ${inputs.name}.`)
this.context.status(`Creating`)
inputs.arn = await createRole({ iam, ...inputs })
} else {
inputs.arn = prevRole.arn
if (inputsChanged(prevRole, inputs)) {
this.context.status(`Updating`)
if (prevRole.service !== inputs.service) {
this.context.debug(`Updating service for role ${inputs.name}.`)
await updateAssumeRolePolicy({ iam, ...inputs })
}
if (!equals(prevRole.policy, inputs.policy)) {
this.context.debug(`Updating policy for role ${inputs.name}.`)
await removeRolePolicy({ iam, ...inputs })
await addRolePolicy({ iam, ...inputs })
}
}
}
// todo we probably don't need this logic now that
// we auto generate unconfigurable names
if (this.state.name && this.state.name !== inputs.name) {
this.context.status(`Replacing`)
this.context.debug(`Deleting/Replacing role ${inputs.name}.`)
await deleteRole({ iam, name: this.state.name, policy: inputs.policy })
}
this.state.name = inputs.name
this.state.arn = inputs.arn
this.state.service = inputs.service
this.state.policy = inputs.policy
this.state.region = inputs.region
await this.save()
this.context.debug(`Saved state for role ${inputs.name}.`)
const outputs = {
name: inputs.name,
arn: inputs.arn,
service: inputs.service,
policy: inputs.policy
}
this.context.debug(`Role ${inputs.name} was successfully deployed to region ${inputs.region}.`)
this.context.debug(`Deployed role arn is ${inputs.arn}.`)
return outputs
}
async remove() {
this.context.status(`Removing`)
if (!this.state.name) {
this.context.debug(`Aborting removal. Role name not found in state.`)
return
}
const iam = new aws.IAM({
region: this.state.region,
credentials: this.context.credentials.aws
})
this.context.debug(`Removing role ${this.state.name} from region ${this.state.region}.`)
await deleteRole({ iam, ...this.state })
this.context.debug(
`Role ${this.state.name} successfully removed from region ${this.state.region}.`
)
const outputs = {
name: this.state.name,
arn: this.state.arn,
service: this.state.service,
policy: this.state.policy
}
this.state = {}
await this.save()
return outputs
}
}
module.exports = AwsIamRole