forked from awslabs/aws-servicebroker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample-main.yaml
202 lines (198 loc) · 7.57 KB
/
example-main.yaml
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
AWSTemplateFormatVersion: 2010-09-09
Description: AWS Service Broker - S3 Example Custom Service
Metadata:
# Service Broker metadata section
AWS::ServiceBroker::Specification:
# Required - only valid value is 1.0 at this time
Version: 1.0
# Required - service definition name, all lowercase [a-z0-9-].*
Name: s3-example
# Required - at least one service plan must be defined
ServicePlans:
# plan name all lowercase [a-z0-9-].*
plana:
# Optional - enforce values for template parameters
ParameterValues:
BucketAccessControl: Private
# Optional - used to enhance platforms with web ui
DisplayName: Plan A
# Optional - used to enhance platforms with web ui
Description: Short plan description
# Optional - used to enhance platforms with web ui
LongDescription: Long plan description
planb: {}
# Optional - Parameter names here can be updated by calling osb update.
# If none are specified the ServiceInstance will not be updateable.
UpdatableParameters: []
# Optional - used to enhance platforms with web ui
Tags:
- AWS
- Custom Service
# Optional - used to enhance platforms with web ui
DisplayName: name used in web ui
# Optional - used to enhance platforms with web ui
LongDescription: description used in web ui
# Optional - used to enhance platforms with web ui
ImageUrl: https://hostname/path/to/icon.png
# Optional - used to enhance platforms with web ui
DocumentationUrl: https://hostname/path-to-documentation/'
# Optional - used to enhance platforms with web ui
ProviderDisplayName: Amazon Web Services
# Optional - used to enhance platforms with web ui
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: S3 Bucket Settings
Parameters:
- BucketAccessControl
ParameterLabels:
BucketAccessControl:
default: Bucket Access Control
# Parameters can be set as properties when making a provision call to the broker
# Parameters without default values will be marked as required.
Parameters:
BucketAccessControl:
Description: define if the bucket can be accessed from public or private locations
Type: String
# Using allowed values will create a drop down in platform ui
AllowedValues:
- Private
- BucketOwnerFullControl
# providing a default makes the parameter optional
Default: Private
Resources:
# Resource being provisioned, in this example an S3 bucket
S3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: !Ref BucketAccessControl
# Policies can be created for use in bind operations
S3Full:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub "S3Full-${S3Bucket}"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- s3:DeleteObject
- s3:GetObject
- s3:PutObject
Effect: Allow
Resource: !Sub ${S3Bucket.Arn}/*
# multiple scopes can be defined
S3Read:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub "S3Read-${S3Bucket}"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action: s3:GetObject
Effect: Allow
Resource: !Sub ${S3Bucket.Arn}/*
# The resources below are needed if static iam access keys are to be returned on bind
AccessKeyCustomResourceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: iam_user_creation
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:CreateAccessKey
- iam:PutUserPolicy
- iam:ListAttachedUserPolicies
- iam:DeleteUserPolicy
- iam:AttachUserPolicy
- iam:DeleteUser
- iam:ListUserPolicies
- iam:DetachUserPolicy
- iam:CreateUser
- iam:DeleteAccessKey
- iam:ListAccessKeys
- ssm:DeleteParameters
- ssm:PutParameter
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
AccessKeyCustomResourceLambda:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role:
Fn::GetAtt: [ AccessKeyCustomResourceRole, Arn ]
Code:
ZipFile: |-
import cfnresponse
import random
import string
import boto3
import traceback
alnum = string.ascii_uppercase + string.ascii_lowercase + string.digits
iam_client = boto3.client('iam')
ssm_client = boto3.client('ssm')
def handler(event, context):
response_code = cfnresponse.SUCCESS
response_data = {}
if event['RequestType'] == 'Create':
phys_id = ''.join(random.choice(alnum) for _ in range(16))
else:
phys_id = event['PhysicalResourceId']
response_data['AsbAccessKeyId'] = 'AsbAccessKeyId-%s' % phys_id
response_data['AsbSecretAccessKey'] = 'AsbSecretAccessKey-%s' % phys_id
try:
username = event['ResourceProperties']['Username']
if event['RequestType'] == 'Create':
response = iam_client.create_access_key(UserName=username)
aws_access_key_id = response['AccessKey']['AccessKeyId']
secret_access_key = response['AccessKey']['SecretAccessKey']
ssm_client.put_parameter(Name=response_data['AsbAccessKeyId'], Value=aws_access_key_id, Type='SecureString')
ssm_client.put_parameter(Name=response_data['AsbSecretAccessKey'], Value=secret_access_key, Type='SecureString')
elif event['RequestType'] == 'Update':
print('Update operation unsupported')
response_code = cfnresponse.FAILED
elif event['RequestType'] == 'Delete':
for access_key in iam_client.list_access_keys(UserName=username)['AccessKeyMetadata']:
iam_client.delete_access_key(UserName=username, AccessKeyId=access_key['AccessKeyId'])
ssm_client.delete_parameters(Names=[response_data['AsbAccessKeyId'], response_data['AsbSecretAccessKey']])
cfnresponse.send(event, context, response_code, response_data, phys_id)
except Exception as e:
print(str(e))
traceback.print_exc()
cfnresponse.send(event, context, cfnresponse.FAILED, response_data, phys_id)
Runtime: python2.7
Timeout: '60'
IAMUser:
Type: AWS::IAM::User
AccessKeyCustomResource:
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt AccessKeyCustomResourceLambda.Arn
Username: !Ref IAMUser
# Outputs are used to define what is returned on bind
Outputs:
BucketName:
Value: !Ref S3Bucket
BucketArn:
Value: !GetAtt S3Bucket.Arn
S3Region:
Value: !Ref AWS::Region
# Secret outputs can be stored in ssm and then outputted with a "ssm:" prefix, the broker will fetch values on bind
S3AwsAccessKeyId:
Value: !Sub "ssm:${AccessKeyCustomResource.AsbAccessKeyId}"
S3AwsSecretAccessKey:
Value: !Sub "ssm:${AccessKeyCustomResource.AsbSecretAccessKey}"