From 7d57425bae30706443f816f17833bf2bf5a32cc9 Mon Sep 17 00:00:00 2001 From: bhoff Date: Tue, 15 Oct 2024 14:20:32 -0700 Subject: [PATCH] IT-3869: Retrieve SSM Parameters in Automation execution Lambda --- org-formation/090-systems-manager/README.md | 9 +++-- .../Scheduled-Script-Automation.yaml | 33 +++++++++++++++---- org-formation/090-systems-manager/_tasks.yaml | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/org-formation/090-systems-manager/README.md b/org-formation/090-systems-manager/README.md index 990f2b37..953e65e6 100644 --- a/org-formation/090-systems-manager/README.md +++ b/org-formation/090-systems-manager/README.md @@ -22,12 +22,15 @@ which is referenced from the This folder contain the automation required to run a given script on appropriately tagged EC2 instances on a schedule. Its primary application is to run the script that installs the Stack Armor monitoring agent on a set of target EC2s but it's general enough that it can be used to run other scripts on other machines. It allows passing in script -parameters as key-value pairs which are passed to the script as environment variables. +parameters as key-value pairs. In each pair the 'value' is the name of a secure SSM parameter which is then +retrieved, paired with the key and passed along to the script as an environment variable. E.g., if we pass in "foo:/my/param" +and if SSM parameter store contains the value "bar" for the secure parameter named "/my/param", then the environment +variable "foo=bar" will be passed along to the script. -WARNING: This automation depends upon EC2 instances behing appropriately tagged and will not work if the tags +WARNING: This automation depends upon EC2 instances being appropriately tagged and will not work if the tags are absent. A likely approach is to specify the tags in the CloudFormation template that deploys the target instances. ### Deployments The templates for setting up the AWS system manager are deployed -using org-formation +using org-formation. diff --git a/org-formation/090-systems-manager/Scheduled-Script-Automation.yaml b/org-formation/090-systems-manager/Scheduled-Script-Automation.yaml index 5a706cb8..fb4fcef1 100644 --- a/org-formation/090-systems-manager/Scheduled-Script-Automation.yaml +++ b/org-formation/090-systems-manager/Scheduled-Script-Automation.yaml @@ -50,8 +50,8 @@ Parameters: ScriptParameters: Type: String Description: >- - space delimited list of environment name-value pairs in the format name:value, - e.g., ENVNAME1:envval1 ENVNAME2:envval2 + space delimited list of environment name-ssm parameter store pairs in the format env-name:ssm-name, + e.g., ENVNAME1:/ssm/name1 ENVNAME2:/ssm/name2 TargetTagName: Type: String Description: Name of the tag for instances to target. @@ -129,20 +129,25 @@ Resources: Action: - ssm:StartAutomationExecution Resource: - - Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${AutomationDocumentScriptExecution}:$DEFAULT + - Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${AutomationDocumentScriptExecution}:$DEFAULT + - Effect: Allow + Action: + - ssm:GetParameter + Resource: + - Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter* - Action: iam:PassRole Resource: - Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:role/AWS-SystemsManager-AutomationAdministrationRole + - Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:role/AWS-SystemsManager-AutomationAdministrationRole Effect: Allow - Action: logs:CreateLogGroup Resource: - Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:* + - Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:* Effect: Allow - Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/MultiAccountScriptExecution:* + - Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/MultiAccountScriptExecution:* Effect: Allow MultiAccountScriptExecutionLambdaFunction: Type: AWS::Lambda::Function @@ -180,6 +185,20 @@ Resources: AutomationDocumentScriptExecution=os.environ['AutomationDocumentScriptExecution'] ScriptUrl=os.environ['ScriptUrl'] ScriptParameters=os.environ['ScriptParameters'] + ScriptParametersArray = str(ScriptParameters).split() + ScriptKeyValueParameters = None + for envParamNameString in ScriptParametersArray: + envParamNamePair = envParamNameString.split(":") + if len(envParamNamePair) != 2: + raise Exception(f"Expected key:value pair but got {envParamNameString}") + envVarName=envParamNamePair[0] + ssmParamName=envParamNamePair[1] + envVarValue = client.get_parameter(Name=ssmParamName, WithDecryption=True)['Parameter']['Value'] + keyValuePair=envVarName+":"+envVarValue + if ScriptKeyValueParameters is None: + ScriptKeyValueParameters = keyValuePair + else: + ScriptKeyValueParameters += " "+keyValuePair response = client.start_automation_execution( DocumentName=f'{AutomationDocumentScriptExecution}', @@ -190,7 +209,7 @@ Resources: 'TargetTagValue' : [TargetTagValue], 'ScriptUrl' : [ScriptUrl], 'ExecutionTimeoutSeconds': [ExecutionTimeoutSeconds], - 'SsmParameterNameToEnvvarMap' : [ScriptParameters] + 'SsmParameterNameToEnvvarMap' : [ScriptKeyValueParameters] }, TargetLocations=[ { diff --git a/org-formation/090-systems-manager/_tasks.yaml b/org-formation/090-systems-manager/_tasks.yaml index 15e934d7..07b5faec 100644 --- a/org-formation/090-systems-manager/_tasks.yaml +++ b/org-formation/090-systems-manager/_tasks.yaml @@ -88,4 +88,4 @@ StackArmorAgentInstallation: TargetTagName: execute-script TargetTagValue: install-stack-armor-agent ScriptUrl: https://raw.githubusercontent.com/Sage-Bionetworks/infra-utils/v1.0.11/stack-armor/install-nessus-agent.sh - ScriptParameters: STACK_ARMOR_KEY:'{{resolve:ssm-secure:/stack-armor/install-nessus-key}}' + ScriptParameters: STACK_ARMOR_KEY:/stack-armor/install-nessus-key