Skip to content

Instantly share code, notes, and snippets.

@sonodar
Last active April 3, 2024 06:24
Show Gist options
  • Save sonodar/b3c80c8b9e60f4e6dcda9108c46a6089 to your computer and use it in GitHub Desktop.
Save sonodar/b3c80c8b9e60f4e6dcda9108c46a6089 to your computer and use it in GitHub Desktop.
Get secret parameters from Amazon EC2 Parameter Store
if (process.argv.length < 3) {
throw `Usage: ${process.argv[1]} path_prefix`
}
const PATH_PREFIX = process.argv[2]
const path = require('path')
const AWS = require('aws-sdk')
const ssm = new AWS.SSM()
function getParametersByPath(nextToken, callback) {
const params = { Path: PATH_PREFIX, Recursive: true, WithDecryption: true }
if (nextToken) params['NextToken'] = nextToken
ssm.getParametersByPath(params, (err, data) => {
if (err) throw err
callback(data)
})
}
function printParameter(parameter) {
const envName = path.basename(parameter.Name)
console.log(`${envName}="${parameter.Value}"`)
}
function handleResponse(response) {
if (response.Parameters.length === 0) return
response.Parameters.forEach(printParameter)
if (!response.NextToken) return
getParametersByPath(response.NextToken, handleResponse)
}
getParametersByPath(null, handleResponse)
<?php
use Aws\Ssm\SsmClient;
function get_parameters_by_path(SsmClient &$ssm, $parameter_path, $next_token = null)
{
$params = [
'Path' => $parameter_path,
'Recursive' => true,
'WithDecryption' => true,
'MaxResults' => 500,
];
if ($next_token) {
$params['NextToken'] = $next_token;
}
return $ssm->getParametersByPath($params);
}
function get_all_parameters()
{
$parameter_path = getenv('AWS_PARAMETER_PATH');
if (empty($parameter_path)) {
return [];
}
$ssm = new SsmClient(['region' => getenv('AWS_REGION')]);
$next_token = null;
while(true)
{
$response = get_parameters_by_path($ssm, $parameter_path, $next_token);
foreach ($response['Parameters'] as $parameter) {
yield $parameter['Name'] => $parameter['Value'];
}
if (!empty($response['NextToken'])) {
$next_token = $response['NextToken'];
continue;
}
break;
}
return [];
}
foreach (get_all_parameters() as $name => $value) {
$basename = pathinfo($name, PATHINFO_BASENAME);
echo "{mb_strtoupper($basename)}=\"${value}\"\n";
}
#!/usr/bin/env python
from os import path
from sys import argv
import boto3
if len(argv) < 2:
raise "Usage: %s path" % argv[0]
PATH = argv[1]
SSM = boto3.client('ssm')
def get_parameters_by_path(next_token = None):
params = {
'Path': PATH,
'Recursive': True,
'WithDecryption': True
}
if next_token is not None:
params['NextToken'] = next_token
return SSM.get_parameters_by_path(**params)
def parameters():
next_token = None
while True:
response = get_parameters_by_path(next_token)
parameters = response['Parameters']
if len(parameters) == 0:
break
for parameter in parameters:
yield parameter
if 'NextToken' not in response:
break
next_token = response['NextToken']
def print_env_vars(parameter):
env_name = path.basename(parameter['Name'])
env_value = parameter['Value']
print("%s=\"%s\"" % (env_name, env_value))
def main():
for parameter in parameters():
print_env_vars(parameter)
if __name__ == "__main__":
main()
#!/usr/bin/env ruby
require 'aws-sdk'
raise "Usage: #{$0} path" if ARGV[0].nil?
PATH = ARGV[0]
SSM = Aws::SSM::Client.new
def get_parameters_by_path(next_token = nil)
params = {
path: PATH,
recursive: true,
with_decryption: true,
}
params[:next_token] = next_token unless next_token.nil?
SSM.get_parameters_by_path(params)
end
def parameters
next_token = nil
while true
response = get_parameters_by_path(next_token)
break if response.parameters.empty?
response.parameters.each { |parameter| yield parameter }
next_token = response.next_token
break if next_token.nil?
end
end
def print_env_vars(parameter)
env_name = File.basename(parameter.name)
env_value = parameter.value
puts "#{env_name}=\"#{env_value}\""
end
parameters { |p| print_env_vars p }
use aws_sdk_ssm::{operation::get_parameters_by_path::GetParametersByPathOutput, types::Parameter};
#[::tokio::main]
async fn main() -> Result<(), aws_sdk_ssm::Error> {
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {} <path>", args[0]);
std::process::exit(1);
};
let path = &args[1];
let config = aws_config::load_from_env().await;
let ssm = aws_sdk_ssm::Client::new(&config);
for parameter in get_all_parameters_by_path(path, &ssm).await? {
// path prefix を除去する
let name = parameter
.name
.unwrap_or_default()
.replace(&format!("{}/", path), "");
println!("{}=\"{}\"", name, parameter.value.unwrap_or_default());
}
Ok(())
}
async fn get_all_parameters_by_path(
path: &str,
client: &aws_sdk_ssm::Client,
) -> Result<Vec<Parameter>, aws_sdk_ssm::Error> {
let mut parameters = Vec::new();
let mut next_token = None;
loop {
let response = get_parameters_by_path(path, next_token, client).await?;
parameters.extend(response.parameters.unwrap_or_default());
if let Some(token) = response.next_token {
next_token = Some(token);
} else {
break;
}
}
Ok(parameters)
}
async fn get_parameters_by_path(
path: &str,
next_token: Option<String>,
client: &aws_sdk_ssm::Client,
) -> Result<GetParametersByPathOutput, aws_sdk_ssm::Error> {
let mut request = client
.get_parameters_by_path()
.path(path)
.recursive(true)
.with_decryption(true);
if let Some(token) = next_token {
request = request.next_token(token);
}
let response = request.send().await?;
Ok(response)
}
#!/usr/bin/env bash
# Usage: get_ssm_parameters.sh aws_region path_prefix
# $1 aws_region : SSM Parameter Region (ex. ap-northeast-1)
# $2 path_prefix: SSM Parameter Path prefix (ex. /app/api/staging)
# IAM Policy example:
# {
# "Version": "",
# "Statement": [{
# "Sid": ""
# "Effect": "Allow"
# "Action": ["ssm:GetParametersByPath]"
# "Resource": "arn:aws:ssm:YOUR_REGION:YOUR_AWS_ACCOUNT_ID:parameter/app/api/staging/*"
# }]
# }
set +x
# jq is required.
if [ $# -lt 2 ]; then
echo "Usage: $0 aws_region path_prefix" 1>&2
exit 1
fi
readonly AWS_REGION="${1}"
readonly PATH_PREFIX="${2}"
# $1 nextToken
get_parameters_by_path() {
local nextToken="${1}"
aws ssm get-parameters-by-path --region "${AWS_REGION}" \
--path "${PATH_PREFIX}" --recursive --with-decryption \
$([ -z "${nextToken}" ] || echo "--next-token ${nextToken}")
}
# $1 parameterName
# $2 parameterValue
print_env_vars() {
local envName=$(basename "${1}")
local envValue="${2}"
echo "${envName}=\"${envValue}\""
}
print_parameters() {
local nextToken=""
while true; do
responseJson=$(get_parameters_by_path "${nextToken}")
declare -i parameterCount=$(echo "${responseJson}" | jq -c '.Parameters[].Name' | wc -l)
[ ${parameterCount} -lt 1 ] && break
echo "${responseJson}" | jq -r '.Parameters[]|[.Name,.Value] | @sh' | while read LINE; do
declare -a nameAndValue=($(echo "$LINE" | tr -d \'))
print_env_vars "${nameAndValue[@]}"
done
nextToken=$(echo "${responseJson}" | jq -r '.NextToken')
if [ -z "${nextToken}" ] || [[ "${nextToken}" == "null" ]]; then
break
fi
done
}
print_parameters
@realsby
Copy link

realsby commented Oct 30, 2019

get_ssm_parameters.sh it is cool but it does not work properly if the parameter's value is "*"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment