Skip to content

Commit

Permalink
- Fixed EBS EC2 Launch Bundle to work with Ubuntu nvme drives
Browse files Browse the repository at this point in the history
- Implemented SystemsManagerSession IAM policy
  • Loading branch information
gitwater committed Nov 5, 2021
1 parent cabf297 commit e605cc3
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 20 deletions.
91 changes: 74 additions & 17 deletions src/paco/application/ec2_launch_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1090,8 +1090,12 @@ def lb_add_ebs(self, bundle_name, resource):
. {self.paco_base_path}/EC2Manager/ec2lm_functions.bash
INSTANCE_AMI_TYPE={resource.instance_ami_type_generic}
NVME_CLI=nvme-cli
EBS_MOUNT_FOLDER_LIST=ebs_mount_folder_list
EBS_VOLUME_UUID_LIST=ebs_volume_uuid_list
LINUX_DEVICE=""
# Attach EBS Volume
function ec2lm_attach_ebs_volume() {{
Expand All @@ -1107,21 +1111,62 @@ def lb_add_ebs(self, bundle_name, resource):
return 1
}}
function ec2lm_volume_linux_device() {{
if [ "$INSTANCE_AMI_TYPE" == "ubuntu" ] ; then
EBS_VOLUME_ID=$1
for DEVICE in $(lsblk -n -o NAME -p -d |grep -v loop)
do
DEVICE_VOLUME_ID="vol-"$(nvme id-ctrl -H $DEVICE |grep 'sn : vol' | awk -F 'vol' '{{print $2}}')
if [ "$DEVICE_VOLUME_ID" == "$EBS_VOLUME_ID" ]; then
echo $DEVICE
return 0
fi
done
return 1
else
DEVICE=$2
OUTPUT=$(file -s $DEVICE)
if [[ $OUTPUT == *"No such file or directory"* ]] ; then
return 1
else
echo $DEVICE
return 0
fi
fi
return 1
}}
# Checks if a volume has been attached
# ec2lm_volume_is_attached <device>
# Return: 0 == True
# 1 == False
function ec2lm_volume_is_attached() {{
DEVICE=$1
OUTPUT=$(file -s $DEVICE)
if [[ $OUTPUT == *"No such file or directory"* ]] ; then
if [ "$INSTANCE_AMI_TYPE" == "ubuntu" ] ; then
EBS_VOLUME_ID=$1
for DEVICE in $(lsblk -n -o NAME -p -d |grep -v loop)
do
DEVICE_VOLUME_ID="vol-"$(nvme id-ctrl -H $DEVICE |grep 'sn : vol' | awk -F 'vol' '{{print $2}}')
if [ "$DEVICE_VOLUME_ID" == "$EBS_VOLUME_ID" ]; then
echo "Made it!"
return 0
fi
done
return 1
else
DEVICE=$2
OUTPUT=$(file -s $DEVICE)
if [[ $OUTPUT == *"No such file or directory"* ]] ; then
return 1
else
return 0
fi
fi
return 0
}}
# Checks if a volume has been attached
# ec2lm_volume_is_attached <device>
# Get the Volume UUID
# ec2lm_get_volume_uuid <device>
# Return: 0 == True
# 1 == False
function ec2lm_get_volume_uuid() {{
Expand Down Expand Up @@ -1150,9 +1195,9 @@ def lb_add_ebs(self, bundle_name, resource):
fi
# Setup the mount folder
if [ -e $MOUNT_FOLDER ] ; then
mv $MOUNT_FOLDER ${{MOUNT_FOLDER%%/}}.old
fi
# if [ -e $MOUNT_FOLDER ] ; then
# mv $MOUNT_FOLDER ${{MOUNT_FOLDER%%/}}.old
# fi
mkdir -p $MOUNT_FOLDER
TIMEOUT_SECS=300
Expand All @@ -1163,39 +1208,46 @@ def lb_add_ebs(self, bundle_name, resource):
echo "[ERROR] EC2LM: EBS: $OUTPUT"
cat /tmp/ec2lm_attach.output
exit 1
else
echo $OUTPUT
fi
# Initialize filesystem if blank
echo "EC2LM: EBS: Waiting for volume to become available: $EBS_DEVICE"
echo "EC2LM: EBS: Waiting for volume to become available: $EBS_VOLUMEID on $EBS_DEVICE"
TIMEOUT_SECS=30
OUTPUT=$(ec2lm_timeout $TIMEOUT_SECS ec2lm_volume_is_attached $EBS_DEVICE)
OUTPUT=$(ec2lm_timeout $TIMEOUT_SECS ec2lm_volume_is_attached $EBS_VOLUME_ID $EBS_DEVICE)
if [ $? -eq 1 ] ; then
echo "EC2LM: EBS: Error: Unable to detect the attached volume $EBS_VOLUME_ID to $INSTANCE_ID as $EBS_DEVICE."
echo "[ERROR] EC2LM: EBS: $OUTPUT"
exit 1
fi
LINUX_DEVICE=$(ec2lm_volume_linux_device $EBS_VOLUME_ID $EBS_DEVICE)
# LINUX_DEVICE is set in ec2lm_volume_is_attached()
echo "EC2LM: EBS: Initializing Volume $EBS_VOLUME_ID on linux device $LINUX_DEVICE"
# Format: Make a filesystem if the device
FILE_FMT=$(file -s $EBS_DEVICE)
BLANK_FMT="$EBS_DEVICE: data"
FILE_FMT=$(file -s $LINUX_DEVICE)
BLANK_FMT="$LINUX_DEVICE: data"
if [ "$FILE_FMT" == "$BLANK_FMT" ] ; then
echo "EC2LM: EBS: Initializing EBS Volume with FS type $FILESYSTEM"
/sbin/mkfs -t $FILESYSTEM $EBS_DEVICE
/sbin/mkfs -t $FILESYSTEM $LINUX_DEVICE
fi
# Setup fstab
echo "EC2LM: EBS: Getting Volume UUID for $EBS_DEVICE"
echo "EC2LM: EBS: Getting Volume UUID for $LINUX_DEVICE"
TIMEOUT_SECS=30
VOLUME_UUID=$(ec2lm_timeout $TIMEOUT_SECS ec2lm_get_volume_uuid $EBS_DEVICE)
VOLUME_UUID=$(ec2lm_timeout $TIMEOUT_SECS ec2lm_get_volume_uuid $LINUX_DEVICE)
if [ $? -eq 1 ] ; then
echo "[ERROR] EC2LM: EBS: Unable to get volume UUID for $EBS_DEVICE"
echo "[ERROR] EC2LM: EBS: Unable to get volume UUID for $LINUX_DEVICE"
echo "[ERROR] EC2LM: EBS: Error: $OUTPUT"
/sbin/blkid
exit 1
fi
# /etc/fstab entry
echo "EC2LM: EBS: $EBS_DEVICE UUID: $VOLUME_UUID"
echo "EC2LM: EBS: $LINUX_DEVICE UUID: $VOLUME_UUID"
FSTAB_ENTRY="UUID=$VOLUME_UUID $MOUNT_FOLDER $FILESYSTEM defaults,nofail 0 2"
echo "EC2LM: EBS: Configuring /etc/fstab: $FSTAB_ENTRY"
grep -v -E "^UUID=$VOLUME_UUID" /etc/fstab >/tmp/fstab.ebs_new
Expand All @@ -1215,6 +1267,11 @@ def lb_add_ebs(self, bundle_name, resource):
function run_launch_bundle()
{{
# Initialize
if [ "$INSTANCE_AMI_TYPE" == "ubuntu" ] ; then
apt-get install nvme-cli -y
export NVME_CLI=nvme-cli
fi
# Process Mounts
:>$EBS_MOUNT_FOLDER_LIST".new"
:>$EBS_VOLUME_UUID_LIST".new"
Expand Down
76 changes: 75 additions & 1 deletion src/paco/cftemplates/iam_user_account_delegates.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from awacs.aws import Allow, Action, Principal, Statement, Condition, MultiFactorAuthPresent, PolicyDocument, StringEquals
from awacs.aws import Allow, Action, Principal, Statement, Condition, MultiFactorAuthPresent, PolicyDocument, StringLike
from awacs.aws import Bool as AWACSBool
from awacs.sts import AssumeRole
from getpass import getpass
Expand All @@ -7,6 +7,7 @@
from paco.core.exception import StackException
from paco.core.exception import PacoErrorCode
from paco.models.references import Reference
from paco.models import schemas
import troposphere
import troposphere.cloudformation
import troposphere.iam
Expand Down Expand Up @@ -122,6 +123,76 @@ def init_custompolicy_permission(self, permission_config, assume_role_res):
)
self.template.add_resource(managed_policy_res)


def init_systemsmanagersession_permission(self, permission_config, assume_role_res):
if 'ManagedPolicyArns' not in assume_role_res.properties.keys():
assume_role_res.properties['ManagedPolicyArns'] = []

resource_group_condition_list = []
for resource in permission_config.resources:
resource_ref = Reference(resource)
# Initialize The network environments that we need access into
resource_obj = resource_ref.get_model_obj(self.paco_ctx.project)
if schemas.IResourceGroup.providedBy(resource_obj):
resource_group_condition_list.append(
StringLike({
'ssm:resourceTag/Paco-Application-Group-Name': resource_obj.name
})
)

if len(resource_group_condition_list) == 0:
return

statement_list = []
statement_list.append(
Statement(
Sid='SessionManagerStartSession',
Effect=Allow,
Action=[
Action('ssm', 'StartSession'),
],
Resource=[
'arn:aws:ec2:*:*:instance/*',
'arn:aws:ssm:*::document/AWS-StartPortForwardingSession'
],
Condition=Condition(resource_group_condition_list)
)
)
statement_list.append(
Statement(
Sid='SessionManagerPortForward',
Effect=Allow,
Action=[
Action('ssm', 'StartSession'),
],
Resource=[
'arn:aws:ssm:*::document/AWS-StartPortForwardingSession'
]
)
)
statement_list.append(
Statement(
Sid='SessionManagerTerminateSession',
Effect=Allow,
Action=[
Action('ssm', 'TerminateSession'),
Action('ssm', 'ResumeSession'),
],
Resource=[
'arn:aws:ssm:*:*:session/${aws:username}-*'
]
)
)
managed_policy_res = troposphere.iam.ManagedPolicy(
title=self.create_cfn_logical_id_join(["SystemsManagerSession"]),
PolicyDocument=PolicyDocument(
Version="2012-10-17",
Statement=statement_list
),
Roles=[ troposphere.Ref(assume_role_res) ]
)
self.template.add_resource(managed_policy_res)

def init_deploymentpipelines_permission(self, permission_config, assume_role_res):
if 'ManagedPolicyArns' not in assume_role_res.properties.keys():
assume_role_res.properties['ManagedPolicyArns'] = []
Expand Down Expand Up @@ -276,6 +347,9 @@ def deployment_pipeline_manaul_approval_permissions(self, pipeline_list, assume_
print(f'arn:aws:codepipeline:{self.aws_region}:{self.account_id}:{pipeline_name}:/{stage_type}/Approval\n')


if len(manual_approval_resource_list) == 0:
return

statement_list = []
statement_list.append(
Statement(
Expand Down
14 changes: 12 additions & 2 deletions src/paco/controllers/ctl_iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def init_codebuild_permission(self, permission_config, permissions_by_account):
if permission_config not in permissions_by_account[account_name]:
permissions_by_account[account_name].append(permission_config)

# DeploymentPipelines
# DeploymentPipelines
def init_deploymentpipelines_permission(self, permission_config, permissions_by_account):
"""
Iterates over each pipeline reference and adds its permission config
Expand Down Expand Up @@ -289,7 +289,17 @@ def init_deploymentpipelines_permission(self, permission_config, permissions_by_
if permission_config not in permissions_by_account[account_name]:
permissions_by_account[account_name].append(permission_config)


# DeploymentPipelines
def init_systemsmanagersession_permission(self, permission_config, permissions_by_account):
"""
Iterates over each SystemsManagerSession resource reference and adds its permission config
to the map of permissions by account.
"""
for resource_ref in permission_config.resources:
#resource_ref = Reference(resource)
account_name = resource_ref.split('paco.ref ')[1].split('.')[2]
if permission_config not in permissions_by_account[account_name]:
permissions_by_account[account_name].append(permission_config)

def get_sdb_attribute_value(self, sdb_client, sdb_domain, item_name, attribute_name):
attributes = sdb_client.get_attributes(
Expand Down

0 comments on commit e605cc3

Please sign in to comment.