gpt4 book ai didi

amazon-web-services - 执行 Terraform apply 并承担 AWS 角色

转载 作者:行者123 更新时间:2023-12-03 01:21:48 28 4
gpt4 key购买 nike

我需要执行 Terraform 模板来为 AWS 帐户配置基础设施,我可以通过扮演角色来访问该帐户。

我现在遇到的问题是,我在该 AWS 账户中没有 IAM 用户,因此我没有 aws_access_key_idaws_secret_access_key 来设置另一个命名配置文件在我的 ~/.aws/credentials 中。当我运行命令 terraform apply 时,模板会为我的帐户(而不是其他帐户)创建基础架构。

如何使用您的帐户运行 Terraform 模板,该帐户具有访问另一个 AWS 帐户的服务的角色?

这是我的 Terraform 文件:

# Input variables
variable "aws_region" {
type = "string"
default = "us-east-1"
}

variable "pipeline_name" {
type = "string"
default = "static-website-terraform"
}

variable "github_username" {
type = "string"
default = "COMPANY"
}

variable "github_token" {
type = "string"
}

variable "github_repo" {
type = "string"
}

provider "aws" {
region = "${var.aws_region}"
assume_role {
role_arn = "arn:aws:iam::<AWS-ACCOUNT-ID>:role/admin"
profile = "default"
}
}

# CodePipeline resources
resource "aws_s3_bucket" "build_artifact_bucket" {
bucket = "${var.pipeline_name}-artifact-bucket"
acl = "private"
}

data "aws_iam_policy_document" "codepipeline_assume_policy" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "Service"
identifiers = ["codepipeline.amazonaws.com"]
}
}
}

resource "aws_iam_role" "codepipeline_role" {
name = "${var.pipeline_name}-codepipeline-role"
assume_role_policy = "${data.aws_iam_policy_document.codepipeline_assume_policy.json}"
}

# CodePipeline policy needed to use CodeCommit and CodeBuild
resource "aws_iam_role_policy" "attach_codepipeline_policy" {
name = "${var.pipeline_name}-codepipeline-policy"
role = "${aws_iam_role.codepipeline_role.id}"

policy = <<EOF
{
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning",
"s3:PutObject"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"cloudwatch:*",
"sns:*",
"sqs:*",
"iam:PassRole"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild"
],
"Resource": "*",
"Effect": "Allow"
}
],
"Version": "2012-10-17"
}
EOF
}

# CodeBuild IAM Permissions
resource "aws_iam_role" "codebuild_assume_role" {
name = "${var.pipeline_name}-codebuild-role"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}

resource "aws_iam_role_policy" "codebuild_policy" {
name = "${var.pipeline_name}-codebuild-policy"
role = "${aws_iam_role.codebuild_assume_role.id}"

policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Effect": "Allow",
"Resource": [
"${aws_codebuild_project.build_project.id}"
],
"Action": [
"codebuild:*"
]
},
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
}
]
}
POLICY
}

# CodeBuild Section for the Package stage
resource "aws_codebuild_project" "build_project" {
name = "${var.pipeline_name}-build"
description = "The CodeBuild project for ${var.pipeline_name}"
service_role = "${aws_iam_role.codebuild_assume_role.arn}"
build_timeout = "60"

artifacts {
type = "CODEPIPELINE"
}

environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/nodejs:6.3.1"
type = "LINUX_CONTAINER"
}

source {
type = "CODEPIPELINE"
buildspec = "buildspec.yml"
}
}

# Full CodePipeline
resource "aws_codepipeline" "codepipeline" {
name = "${var.pipeline_name}-codepipeline"
role_arn = "${aws_iam_role.codepipeline_role.arn}"

artifact_store = {
location = "${aws_s3_bucket.build_artifact_bucket.bucket}"
type = "S3"
}

stage {
name = "Source"

action {
name = "Source"
category = "Source"
owner = "ThirdParty"
provider = "GitHub"
version = "1"
output_artifacts = ["SourceArtifact"]

configuration {
Owner = "${var.github_username}"
OAuthToken = "${var.github_token}"
Repo = "${var.github_repo}"
Branch = "master"
PollForSourceChanges = "true"
}
}
}

stage {
name = "Deploy"

action {
name = "DeployToS3"
category = "Test"
owner = "AWS"
provider = "CodeBuild"
input_artifacts = ["SourceArtifact"]
output_artifacts = ["OutputArtifact"]
version = "1"

configuration {
ProjectName = "${aws_codebuild_project.build_project.name}"
}
}
}
}

Update:

根据下面达伦的回答(很有道理),我补充道:

provider "aws" {
region = "us-east-1"
shared_credentials_file = "${pathexpand("~/.aws/credentials")}"
profile = "default"

assume_role {
role_arn = "arn:aws:iam::<OTHER-ACCOUNT>:role/<ROLE-NAME>"
}
}

但是,我遇到了这个错误:

  • provider.aws: The role "arn:aws:iam:::role/" cannot be assumed.

    There are a number of possible causes of this - the most common are:

    • The credentials used in order to assume the role are invalid
    • The credentials do not have appropriate permission to assume the role
    • The role ARN is not valid

我已检查其他账户中的角色,并且可以使用我的账户中的 AWS 控制台切换到该角色。我还检查了AWS指南here

因此:该角色 ARN 是有效的,我确实拥有承担该角色的凭据以及运行堆栈所需的所有权限。

Update

我还尝试过使用拥有所有服务访问权限的新角色。但是,我遇到了这个错误:

Error: Error refreshing state: 2 error(s) occurred:

    * aws_codebuild_project.build_project: 1 error(s) occurred:

* aws_codebuild_project.build_project: aws_codebuild_project.build_project: Error retreiving Projects:

"InvalidInputException: Invalid project ARN: account ID does not match caller's account\n\tstatus code: 400, request id: ..." * aws_s3_bucket.build_artifact_bucket: 1 error(s) occurred:

    * aws_s3_bucket.build_artifact_bucket: aws_s3_bucket.build_artifact_bucket: error getting S3 Bucket CORS

configuration: AccessDenied: Access Denied status code: 403, request id: ..., host id: ...

=====

UPDATE 29 Apr 2019:

根据 @Rolando 的建议,我已将此策略添加到主帐户的用户,我尝试使用该主帐户来承担我计划执行 terraform apply 的其他帐户的角色.

{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<OTHER-ACCOUNT-ID>:role/admin"
}
}

这是属于其他帐户的 admin 角色的信任关系:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<MAIN_ACCOUNT_ID>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}

但是,当我运行此命令时:

aws sts assume-role --role-arn arn:aws:iam::<OTHER-ACCOUNT-ID>:role/admin --role-session-name "RoleSession1" --profile default > assume-role-output.txt

我有这个错误:

An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied

最佳答案

只要您想以特定角色(包括其他帐户)运行命令,我就有一个万无一失的解决方案。我假设您已安装 AWS CLI 工具。您还必须安装jq(从 json 解析和提取数据的简单工具),尽管您可以以任何您希望的方式解析数据。

aws_credentials=$(aws sts assume-role --role-arn arn:aws:iam::1234567890:role/nameOfMyrole --role-session-name "RoleSession1" --output json)

export AWS_ACCESS_KEY_ID=$(echo $aws_credentials|jq '.Credentials.AccessKeyId'|tr -d '"')
export AWS_SECRET_ACCESS_KEY=$(echo $aws_credentials|jq '.Credentials.SecretAccessKey'|tr -d '"')
export AWS_SESSION_TOKEN=$(echo $aws_credentials|jq '.Credentials.SessionToken'|tr -d '"')

第一行分配来自 aws sts 命令的响应并将其放入变量中。最后 3 行将从第一个命令中选择值,并将它们分配给 aws cli 使用的变量。

注意事项:

如果您创建 bash 脚本,也请在其中添加 terraform 命令。您还可以使用上面的行创建一个 bash,然后使用“.”运行它。在前面(即:../get-creds.sh)。这将在当前的 bash shell 上创建变量。

角色过期,请记住角色通常有一小时过期。

您的 shell 现在将具有三个变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN。这意味着它将覆盖您的 ~/.aws/credentials。清除此问题最简单的方法就是启动一个新的 bash session 。

我使用这篇文章作为我的来源来解决这个问题:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html

关于amazon-web-services - 执行 Terraform apply 并承担 AWS 角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55128348/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com