forked from awslabs/aws-systems-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create automation script to attach the volume to the EC2 instance with a simple test * Added test stack * clean attach volumne to create automation assume role
- Loading branch information
1 parent
c7e3fee
commit e07f2fe
Showing
8 changed files
with
456 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Attach EBS Volume | ||
|
||
## Notes | ||
|
||
Initial version will only support attaching an existing volume to an instance. | ||
|
||
## Document Design | ||
|
||
Refer to schema.json | ||
|
||
Document Steps: | ||
1. aws:createStack - Execute CloudFormation Template to attach the volume. | ||
* Parameters: | ||
* Device: {{Device}} - The device name (for example, /dev/sdh or xvdh). | ||
* InstanceId: {{InstanceId}} - The ID of the instance. | ||
* VolumeId: {{VolumeId}} - The ID of the EBS volume. The volume and instance must be within the same Availability Zone. | ||
2. aws:deleteStack - Delete CloudFormation Template. | ||
|
||
## Test script | ||
|
||
Python script will: | ||
1. Create a test stack with an instance and a volume | ||
2. Execute automation document to attach volume to instance | ||
3. Ensure the automation has executed successfully | ||
4. Detach volume | ||
5. Clean up test stack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"description": "Attach EBS Volume", | ||
"schemaVersion": "0.3", | ||
"assumeRole": "{{ AutomationAssumeRole }}", | ||
"parameters": { | ||
"Device": { | ||
"type": "String", | ||
"description": "(Required) The device name (for example, /dev/sdh or xvdh )" | ||
}, | ||
"InstanceId": { | ||
"type": "String", | ||
"description": "(Required) The ID of the instance" | ||
}, | ||
"VolumeId": { | ||
"type": "String", | ||
"description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" | ||
}, | ||
"AutomationAssumeRole": { | ||
"type": "String", | ||
"description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", | ||
"default": "" | ||
} | ||
}, | ||
"mainSteps": [] | ||
} |
24 changes: 24 additions & 0 deletions
24
Automation/AttachEBSVolumes/Documents/CloudFormationTemplates/CloudFormationAttachVolume.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
AWSTemplateFormatVersion: '2010-09-09' | ||
Description: Template to attach a EBS volume to an EC2 Instance | ||
Parameters: | ||
Device: | ||
Description: > | ||
The device name (for example, /dev/sdh or xvdh ) | ||
Type: String | ||
InstanceId: | ||
Description: > | ||
The ID of the instance | ||
Type: String | ||
VolumeId: | ||
Description: > | ||
The ID of the EBS volume. The volume and instance must be within the same Availability Zone | ||
Type: String | ||
Resources: | ||
TestResource: | ||
Type: AWS::EC2::VolumeAttachment | ||
DeletionPolicy: Retain | ||
Properties: | ||
Device: !Ref Device | ||
InstanceId: !Ref InstanceId | ||
VolumeId: !Ref VolumeId |
58 changes: 58 additions & 0 deletions
58
Automation/AttachEBSVolumes/Documents/aws-AttachEBSVolume.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"description": "Attach EBS Volume", | ||
"schemaVersion": "0.3", | ||
"assumeRole": "{{ AutomationAssumeRole }}", | ||
"parameters": { | ||
"Device": { | ||
"type": "String", | ||
"description": "(Required) The device name (for example, /dev/sdh or xvdh )" | ||
}, | ||
"InstanceId": { | ||
"type": "String", | ||
"description": "(Required) The ID of the instance" | ||
}, | ||
"VolumeId": { | ||
"type": "String", | ||
"description": "(Required) The ID of the EBS volume. The volume and instance must be within the same Availability Zone" | ||
}, | ||
"AutomationAssumeRole": { | ||
"type": "String", | ||
"description": "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf. ", | ||
"default": "" | ||
} | ||
}, | ||
"mainSteps": [ | ||
{ | ||
"name": "createDocumentStack", | ||
"action": "aws:createStack", | ||
"inputs": { | ||
"Capabilities": [ | ||
"CAPABILITY_IAM" | ||
], | ||
"StackName": "AttachEBSVolumeStack{{automation:EXECUTION_ID}}", | ||
"Parameters": [ | ||
{ | ||
"ParameterKey": "Device", | ||
"ParameterValue": "{{Device}}" | ||
}, | ||
{ | ||
"ParameterKey": "InstanceId", | ||
"ParameterValue": "{{InstanceId}}" | ||
}, | ||
{ | ||
"ParameterKey": "VolumeId", | ||
"ParameterValue": "{{VolumeId}}" | ||
} | ||
], | ||
"TemplateBody": "..." | ||
} | ||
}, | ||
{ | ||
"name": "deleteCloudFormationTemplate", | ||
"action": "aws:deleteStack", | ||
"inputs": { | ||
"StackName": "AttachEBSVolumeStack{{automation:EXECUTION_ID}}" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
TARGET_DIR = "./Output" | ||
|
||
documents: targetdir createdocuments | ||
@echo "Done making documents" | ||
|
||
targetdir: | ||
@echo "Making $(TARGET_DIR)" | ||
mkdir -p ./Output | ||
|
||
createdocuments: | ||
python ./Setup/create_document.py > ./Output/aws-AttachEBSVolume.json | ||
|
||
test: documents | ||
python -m unittest discover Tests | ||
|
||
clean: | ||
@echo "Removing $(TARGET_DIR)" | ||
@rm -rf ./Output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import os | ||
import sys | ||
|
||
import json | ||
import yaml | ||
|
||
LAMBDA_DIR = os.path.abspath(os.path.join( | ||
os.path.dirname(os.path.realpath(__file__)), | ||
"../Documents/Lambdas" | ||
)) | ||
CFT_DIR = os.path.abspath(os.path.join( | ||
os.path.dirname(os.path.realpath(__file__)), | ||
"../Documents/CloudFormationTemplates" | ||
)) | ||
DOCUMENT_DIR = os.path.abspath(os.path.join( | ||
os.path.dirname(os.path.realpath(__file__)), | ||
"../Documents" | ||
)) | ||
|
||
|
||
def aws_tag_multi_constructor(loader, tag_suffix, node): | ||
if tag_suffix not in ['Ref', 'Condition']: | ||
tag_suffix = "Fn::{}".format(tag_suffix) | ||
|
||
if tag_suffix == "Fn::GetAtt": | ||
result = node.value.split(".") | ||
elif isinstance(node, yaml.ScalarNode): | ||
result = loader.construct_scalar(node) | ||
elif isinstance(node, yaml.SequenceNode): | ||
result = loader.construct_sequence(node) | ||
elif isinstance(node, yaml.MappingNode): | ||
result = loader.construct_mapping(node) | ||
else: | ||
raise "Bad value for {}".format(tag_suffix) | ||
|
||
return {tag_suffix: result} | ||
|
||
|
||
yaml.add_multi_constructor("!", aws_tag_multi_constructor) | ||
|
||
|
||
def insert_lambda_in_cft(template, resource_name, lambda_file): | ||
lambda_file = os.path.normpath(os.path.join(LAMBDA_DIR, lambda_file)) | ||
|
||
with open(lambda_file) as fp: | ||
# to shave some bytes we convert 4 spaces to tab | ||
file_content = fp.read().replace(" ", "\t") | ||
|
||
file_size = len(file_content) | ||
print >> sys.stderr, lambda_file + " is " + str(file_size) + "/4096 of max size" | ||
assert file_size <= 4096, "Lambda function must be less then 4096" | ||
template["Resources"][resource_name]["Properties"]["Code"]["ZipFile"] = file_content | ||
|
||
|
||
def insert_cft_in_document(template, step_name, cft_template): | ||
print >> sys.stderr, "Cloud Formation Template is " + str(len(cft_template)) + "/51200 of max size" | ||
assert len(cft_template) < 51200, "CloudFormation template too long, must be less then 50000" | ||
for step in template["mainSteps"]: | ||
if step["name"] == step_name: | ||
step["inputs"]["TemplateBody"] = cft_template | ||
break | ||
|
||
|
||
def open_cloud_formation_template(file_name): | ||
cloud_formation_file = os.path.normpath(os.path.join(CFT_DIR, file_name)) | ||
with open(cloud_formation_file) as fp: | ||
file_content = fp.read() | ||
|
||
return yaml.load(file_content) | ||
|
||
|
||
def open_document(file_name): | ||
cloud_formation_file = os.path.normpath(os.path.join(DOCUMENT_DIR, file_name)) | ||
with open(cloud_formation_file) as fp: | ||
return json.load(fp) | ||
|
||
|
||
def process(): | ||
# opens the cloud formation template | ||
template = open_cloud_formation_template("CloudFormationAttachVolume.yml") | ||
|
||
# replace document create stack with actual template body. | ||
document = open_document("aws-AttachEBSVolume.json") | ||
insert_cft_in_document(document, "createDocumentStack", yaml.safe_dump(template, indent=2)) | ||
print json.dumps(document, indent=2) | ||
|
||
|
||
if __name__ == '__main__': | ||
process() |
59 changes: 59 additions & 0 deletions
59
Automation/AttachEBSVolumes/Tests/CloudFormationTemplates/TestTemplate.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
AWSTemplateFormatVersion: '2010-09-09' | ||
Description: Test stack for Attach EBS Volumes | ||
Outputs: | ||
InstanceId: | ||
Description: Instance Id | ||
Value: | ||
Ref: Instance0 | ||
VolumeId: | ||
Description: Volume Id | ||
Value: | ||
Ref: Volume0 | ||
AutomationAssumeRoleName: | ||
Description: Automation Assume Role Name | ||
Value: !Ref AutomationAssumeRole | ||
AutomationAssumeRoleARN: | ||
Description: Automation Assume Role ARN | ||
Value: !GetAtt AutomationAssumeRole.Arn | ||
Parameters: | ||
AMI: | ||
Description: AMI ID for instances. | ||
Type: String | ||
INSTANCETYPE: | ||
Description: AMI Instance Type (t2.micro, m1.large, etc.) | ||
Type: String | ||
UserARN: | ||
Description: user ARN | ||
Type: String | ||
Resources: | ||
AutomationAssumeRole: | ||
Type: "AWS::IAM::Role" | ||
Properties: | ||
AssumeRolePolicyDocument: | ||
Version: "2012-10-17" | ||
Statement: | ||
- Effect: "Allow" | ||
Principal: | ||
Service: | ||
- "lambda.amazonaws.com" | ||
- "ssm.amazonaws.com" | ||
Action: | ||
- "sts:AssumeRole" | ||
- Effect: "Allow" | ||
Principal: | ||
AWS: !Ref UserARN | ||
Action: | ||
- "sts:AssumeRole" | ||
ManagedPolicyArns: | ||
- "arn:aws:iam::aws:policy/AdministratorAccess" | ||
Instance0: | ||
Type: AWS::EC2::Instance | ||
Properties: | ||
ImageId: !Ref AMI | ||
InstanceType: !Ref INSTANCETYPE | ||
Volume0: | ||
Type: AWS::EC2::Volume | ||
Properties: | ||
Size: 1 | ||
AvailabilityZone: !GetAtt Instance0.AvailabilityZone |
Oops, something went wrong.