aws 添加启动脚本
We’ve written in a previous article about Rewind’s use of AWS SSM Session Manager and associated IAM policies to allow shell and SSH tunnel access to AWS resources. We also open sourced a small tool we created to make use of SSM easier called aws-connect. But what if we want to allow users to only run a subset of approved commands rather than full shell access on an EC2 instance? We have a solution for that!
我们在上一篇文章中撰写了有关Rewind使用AWS SSM Session Manager和关联的IAM策略以允许Shell和SSH隧道访问AWS资源的文章。 我们还开源了一个我们创建的小工具,称为aws-connect ,它使SSM的使用更加容易。 但是,如果我们要允许用户仅在EC2实例上运行已批准命令的子集而不是对shell进行完全访问,该怎么办? 我们有一个解决方案!
系统管理员文件 (Systems Manager Documents)
AWS Systems manager has a feature called Run Commands which allow you to run scripts or commands on EC2 instances that have the SSM agent installed. The commands are based on documents where a document is usually a script with some optional parameters. The great thing about these SSM documents is that access can be controlled with IAM policies.
AWS Systems Manager具有一项称为“运行命令”的功能,该功能使您可以在安装了SSM代理的EC2实例上运行脚本或命令。 这些命令基于文档,其中文档通常是带有一些可选参数的脚本。 这些SSM文档的妙处在于,可以使用IAM策略控制访问。
So what does an SSM document look like? It’s a YAML or JSON file that looks something like this:
那么,SSM文档是什么样的? 这是一个YAML或JSON文件,看起来像这样:
schemaVersion: "2.2"
description: "Hello World"
parameters:
parameters:
type: "String"
description: "Some text to print"
default: "none"mainSteps:
-
action: "aws:runShellScript"
name: "runShellScript"
inputs:
workingDirectory: "{{.}}"
runCommand:
- "echo 'hello world'"
- "echo {{ parameters }}"
This simple example just takes in some parameters and prints them along with the string “hello world”. SSM documents can be invoked via the AWS console by selecting the document and choosing run command or it can be invoked using the CLI or API. Here’s how we’d invoke this on an instance using the CLI:
这个简单的示例仅接受一些参数,并将它们与字符串“ hello world”一起打印。 可以通过选择文档并选择运行命令,通过AWS控制台调用SSM文档,也可以使用CLI或API调用它。 这是我们如何使用CLI在实例上调用此方法:
aws ssm send-command \
--document-name "admin-hello-world" \
--document-version "4" \
--targets '[{"Key":"InstanceIds","Values":["i-123456789"]}]' \
--parameters '{"parameters":["param1 param2"]}' \
--timeout-seconds 600 \
--max-concurrency "50" \
--max-errors "0" \
--region us-east-1
OK, so we understand the basics of Systems Manager documents, what’s next?
好的,所以我们了解了Systems Manager文档的基础,下一步是什么?
来自Github的SSM文档 (SSM Documents from Github)
While the above sample document shows a script embedded in an SSM document, it is possible to have an SSM document reference code in Github directly (either public or private repos). This is incredibly handy because we can now have all the features Github gives us for source control (including Pull Requests for peer review). We now have curated SSM scripts!
尽管上面的示例文档显示了嵌入在SSM文档中的脚本,但可以直接在Github中拥有SSM文档参考代码(公共或私有存储库)。 这非常方便,因为我们现在可以拥有Github为源代码控制提供的所有功能(包括用于同行评审的请求请求)。 现在,我们已经策划了SSM脚本!
How does an SSM document look when it’s pulling code from Github? The big piece is the addition of an action that is based on aws:downloadContent
从Github提取代码时,SSM文档的外观如何? 最重要的是添加了一个基于aws:downloadContent的操作
- action: "aws:downloadContent"
name: "downloadContent"
inputs:
sourceType: "GitHub"
sourceInfo: "{\"owner\":\"rewindio\", \"repository\":\"my_private_repo\",\"getOptions\" : \"branch:main\",\"path\" :\"scripts/read-only/\", \"tokenInfo\":\"{{ ssm-secure:{{githubTokenLocation}} }}\"}"
destinationPath: "{{ workingDirectory }}"
The important parameter required here is the ssm-secure parameter. This is the path to an AWS parameter store secure string parameter. This parameter must contain a Github Personal Access Token (PAT) that has rights to clone the specified repo. In the example above, the PAT must have clone permissions to the rewindio/my_private_repo repository.
此处所需的重要参数是ssm-secure参数。 这是AWS参数存储安全字符串参数的路径。 此参数必须包含有权克隆指定存储库的Github个人访问令牌(PAT)。 在上面的示例中,PAT必须具有对rewindio / my_private_repo存储库的克隆权限。
Let’s look at this in the context of a full document.
让我们在完整文档的上下文中来看一下。
---
schemaVersion: "2.2"
description: "Run Github script"
parameters:
githubTokenLocation:
type: "String"
description: "Location in ssm param store of your github token"
default: "none"
workingDirectory:
type: "String"
default: ""
description: "(Optional) The path where the content will be downloaded and executed\
\ from on your instance."
maxChars: 4096
executionTimeout:
description: "(Optional) The time in seconds for a command to complete before\
\ it is considered to have failed. Default is 3600 (1 hour). Maximum is 28800\
\ (8 hours)."
type: "String"
default: "3600"
allowedPattern: "([1-9][0-9]{0,3})|(1[0-9]{1,4})|(2[0-7][0-9]{1,3})|(28[0-7][0-9]{1,2})|(28800)"
mainSteps:
- action: "aws:downloadContent"
name: "downloadContent"
inputs:
sourceType: "GitHub"
sourceInfo: "{\"owner\":\"rewindio\", \"repository\":\"my_private_repo\",\"getOptions\" : \"branch:main\",\"path\" :\"scripts/read-only/\", \"tokenInfo\":\"{{ ssm-secure:{{githubTokenLocation}} }}\"}"
destinationPath: "{{ workingDirectory }}"
- precondition:
StringEquals:
- "platformType"
- "Linux"
action: "aws:runShellScript"
name: "runShellScript"
inputs:
runCommand:
- chmod a+x my_script.sh
- ./my_script.sh
workingDirectory: "{{ workingDirectory }}"
timeoutSeconds: "{{ executionTimeout }}"
In this example, the path scripts/read-only from the private github repo rewindio/my_private_repo is cloned. The actual run command then runs a single script from here called my_script.sh.
在此示例中,克隆了来自私有github repo rewindio / my_private_repo的路径脚本/只读。 然后,实际的run命令从此处运行一个名为my_script.sh的脚本。
SSM文档权限 (SSM Document Permissions)
So we have these SSM documents, how can we assign permissions so that only particular users can execute particular documents on specific instances? Here’s a sample IAM policy that we’ll step through:
因此,我们有了这些SSM文档,我们如何分配权限,以便只有特定用户才能在特定实例上执行特定文档? 这是我们将逐步执行的示例IAM策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SessionManagerSendCommandSpecificDocs",
"Effect": "Allow",
"Action": "ssm:SendCommand",
"Resource": "arn:aws:ssm:*:*:document/scripts-read-only-*",
"Condition": {
"BoolIfExists": {
"ssm:SessionDocumentAccessCheck": "true"
}
}
},
{
"Sid": "SessionManagerTomyGreatProductInstances",
"Effect": "Allow",
"Action": [
"ssm:StartSession",
"ssm:SendCommand"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringLike": {
"ssm:resourceTag/product": "myGreatProduct"
}
}
}
]
}
The first block allows access to SSM documents beginning with the prefix scripts-read-only-. Users (or roles) with this policy block will only be able to run documents that are named beginning with scripts-read-only-.
第一个块允许访问以前缀scripts-read-only-开头的SSM文档。 具有此策略块的用户(或角色)将只能运行以scripts-read-only-开头的文档。
The second block allows running commands only on instances that have a tag called product with a value of myGreatProduct.
第二个块仅允许在具有名为product的标签且值为myGreatProduct的实例上运行命令。
Using combinations of these blocks assigned to different IAM users/groups/roles, you can restrict access to specific SSM documents and EC2 instances. In our case, we have a couple of user “profiles” we use depending on what access is needed. This is controlled at the IAM Group level and the appropriate IAM policy assigned for the subset of curated scripts we want to allow access to
使用分配给不同IAM用户/组/角色的这些块的组合,可以限制对特定SSM文档和EC2实例的访问。 在我们的案例中,根据需要的访问权限,我们使用了几个用户“配置文件”。 这是在IAM组级别上控制的,并且为要允许访问的策展脚本的子集分配了适当的IAM策略
自动生成和发布SSM文档(Auto-Generating and Publishing SSM Documents)
We have most of the pieces of this solution in place now. But how can we automatically translate code in a private Github repo to SSM documents automatically? Enter Github actions.
现在,我们已经完成了该解决方案的大部分工作。 但是,我们如何自动将私有Github存储库中的代码自动转换为SSM文档? 输入Github操作。
We’ve created a publicly available Github action which automatically creates SSM documents for code added to a Github repo. This action will generate the correct YAML for the SSM document and fill in the correct script name to execute. The beauty of this is now script authors only need to focus on writing their scripts — they don’t need to know all the syntax or nuances of the SSM document schema.
我们创建了一个公开可用的Github操作,该操作会自动为添加到Github存储库中的代码创建SSM文档。 此操作将为SSM文档生成正确的YAML,并填写要执行的正确脚本名称。 这样做的好处在于,脚本作者现在只需要专注于编写脚本,而无需知道SSM文档模式的所有语法或细微差别。
How do we use this Github action? Here’s a sample workflow (this goes in your .github/workflows folder in the Github repo containing your scripts)
我们如何使用这个Github动作? 这是一个示例工作流程(该流程位于包含您的脚本的Github存储库中的.github / workflows文件夹中)
name: synchronizeSSMon:
push:
branches:
- mainjobs:
release-staging:
strategy:
matrix:
publish-region: [us-east-1, eu-west-1] name: ${{ matrix.publish-region }}-staging
runs-on: ubuntu-latest
env:
PUBLISH_REGIONS: ${{ matrix.publish-region }} steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 - name: get files changed
uses: lots0logs/gh-action-get-changed-files@2.1.4
id: get_files_changed
with:
token: ${{ secrets.GITHUB_TOKEN }} - name: generate ssm yaml file
id: generate_ssm_yaml
uses: rewindio/github-action-generate-ssm-documents@main
env:
FILE_LIST: ${{ steps.get_files_changed.outputs.added }}
PREFIX_FILTER: scripts
DEBUG: True
AWS_ACCESS_KEY_ID: ${{ secrets.STAGING_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.STAGING_AWS_SECRET_ACCESS_KEY }}
REPO_NAME: my_private_repo
REPO_OWNER: rewindio
In this example, SSM documents will be created for any files checked into the repo and pushed to the us-east-1 and eu-west-1 regions. Let’s dig into some of the pieces of this workflow:
在此示例中,将为签入回购协议中的任何文件创建SSM文档,并将其推送到us-east-1和eu-west-1区域。 让我们深入研究一下此工作流程:
jobs:
release-staging:
strategy:
matrix:
publish-region: [us-east-1, eu-west-1]name: ${{ matrix.publish-region }}-staging
runs-on: ubuntu-latest
env:
PUBLISH_REGIONS: ${{ matrix.publish-region }}
This uses the matrix strategy for jobs. Github actions will dynamically create a new job for each entry in the publish-region list, naming it using the region name and setting an environment variable in each job with the name of the region.
这将矩阵策略用于作业。 Github操作将为发布区域列表中的每个条目动态创建一个新作业,使用区域名称对其进行命名,并在每个作业中使用区域名称设置环境变量。
- name: get files changed
uses: lots0logs/gh-action-get-changed-files@2.1.4
id: get_files_changed
with:
token: ${{ secrets.GITHUB_TOKEN }}
This uses a handy public action to get the list of changed files in the current change to the repo. We want to generate SSM documents for each file changed.
这使用方便的公共操作来获取当前对仓库的更改中已更改文件的列表。 我们要为每个更改的文件生成SSM文档。
- name: generate ssm yaml file
id: generate_ssm_yaml
uses: rewindio/github-action-generate-ssm-documents@main
env:
FILE_LIST: ${{ steps.get_files_changed.outputs.added }}
PREFIX_FILTER: scripts
DEBUG: True
AWS_ACCESS_KEY_ID: ${{ secrets.STAGING_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.STAGING_AWS_SECRET_ACCESS_KEY }}
REPO_NAME: my_private_repo
REPO_OWNER: rewindio
Here’s the special sauce. This is our Github action that generates the SSM document(s) for each changed file. In this case, it uses PREFIX_FILTER to only look at changed files under the scripts folder. The AWS keys referenced must be stored as Github encrypted secrets for the repo and the corresponding AWS IAM user must have enough permissions to be able to upload SSM documents (ideally no more than this)
这是特制的酱料。 这是我们的Github动作,可为每个更改的文件生成SSM文档。 在这种情况下,它将使用PREFIX_FILTER仅查看scripts文件夹下的已更改文件。 引用的AWS密钥必须存储为该存储库的Github加密密钥,并且相应的AWS IAM用户必须具有足够的权限才能上传SSM文档(理想情况下,不能超过此数量)
So putting this all together in a simple “what does this do” statement:
因此,将所有内容汇总为一个简单的“这将做什么”语句:
Whenever files are added to this github repo under the scripts folder, a corresponding SSM document will be created in the us-east-1 and eu-west-1 regions.
每当将文件添加到scripts文件夹下的该github存储库时,都会在us-east-1和eu-west-1地区中创建相应的SSM文档。
使用aws-connect调用文档 (Invoking Documents using aws-connect)
The final piece of our solution is an easy way to execute these scripts. Given we already have our aws-connect utility, it made sense to extend this. Here’s an example of it in action:
我们解决方案的最后一部分是执行这些脚本的简便方法。 鉴于我们已经有了aws-connect实用程序,因此有必要对其进行扩展。 这是一个实际的例子:
aws-connect -x i-23323ere3423 \
-r us-east-1 \
-a document \
-d my-ssm-document \
-p my_aws_profile \
-w 'param1 "param 2"' \
-g /devops/github_token \
-c ssm-cloudwatch-logs
We’re asking to run the my-ssm-document ssm document on instance i-23323ere3423, passing parameters param1 and param 2 to the document. The gitub PAT is located in the /devops/github_token SSM parameter store parameter.
我们要求在实例i-23323ere3423上运行my-ssm-documents ssm文档,将参数param1和param 2传递给该文档。 gitub PAT位于/ devops / github_token SSM参数存储参数中。
Pulling it all together then, we’ve got a solution where IAM users can be given access to run a subset of curated scripts against a set of tagged instances. We’ve used this successfully to limit access to more powerful scripts to only our senior engineers and it’s a great example once again of using the incredibly versatile SSM service.
综上所述,我们提供了一个解决方案,可以为IAM用户赋予访问权,以针对一组标记实例运行精选脚本的子集。 我们已经成功地使用了它,将访问更强大的脚本的权限限制为仅由我们的高级工程师来使用,这再次成为使用令人难以置信的通用SSM服务的一个很好的例子。
Like putting these kinds of solutions together? Check our careers page for all the engineering roles we’re hiring today.
喜欢将这些解决方案放在一起吗? 查看我们的职业页面,了解我们今天正在招聘的所有工程职位。
翻译自: https://medium.com/@dnorth98/curated-aws-ssm-scripts-ad68389f55c0
aws 添加启动脚本