我对Terraforms和gitlab CI还是很陌生,我在这里尝试做一些事情。
我想使用Terraform创建一个IAM用户和一个S3存储桶。使用策略允许该IAM用户对该S3存储桶进行某些操作。将IAM用户的凭据保存在工件中。 现在,以上内容将成为我的核心模块。
核心模块如下所示:
aws-s3-iam-combo.git
的内容(用于运行所有Terraform的IAM用户的凭据,例如 admin-user ,将存储在gitlab机密中。)
main.tf
resource "aws_s3_bucket" "bucket" {
bucket = "${var.name}"
acl = "private"
force_destroy = "true"
tags {
environment = "${var.tag_environment}"
team = "${var.tag_team}"
}
policy =<<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "${aws_iam_user.s3.arn}"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::${var.name}",
"arn:aws:s3:::${var.name}/*"
]
}
]
}
EOF
}
resource "aws_iam_user" "s3" {
name = "${var.name}-s3"
force_destroy = "true"
}
resource "aws_iam_access_key" "s3" {
user = "${aws_iam_user.s3.name}"
}
resource "aws_iam_user_policy" "s3_policy" {
name = "${var.name}-policy-s3"
user = "${aws_iam_user.s3.name}"
policy =<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::${var.name}",
"arn:aws:s3:::${var.name}/*"
]
}
]
}
EOF
}
outputs.tf
output "bucket" {
value = "${aws_s3_bucket.bucket.bucket}"
}
output "bucket_id" {
value = "${aws_s3_bucket.bucket.id}"
}
output "iam_access_key_id" {
value = "${aws_iam_access_key.s3.id}"
}
output "iam_access_key_secret" {
value = "${aws_iam_access_key.s3.secret}"
}
variables.tf
variable "name" {
type = "string"
}
variable "tag_team" {
type = "string"
default = ""
}
variable "tag_environment" {
type = "string"
default = ""
}
variable "versioning" {
type = "string"
default = false
}
variable "profile" {
type = "string"
default = ""
}
该组织中现在需要创建S3存储桶的任何人都需要创建一个新的存储库,格式如下:
main.tf
module "aws-s3-john-doe" {
source = "git::https://git@gitlab-address/terraform/aws-s3-iam-combo.git?ref=v0.0.1"
name = "john-doe"
tag_team = "my_team"
tag_environment = "staging"
}
gitlab-ci.yml
stages:
- plan
- apply
plan:
image: hashicorp/terraform
stage: plan
script:
- terraform init
- terraform plan
apply:
image: hashicorp/terraform
stage: apply
script:
- terraform init
- terraform apply
when: manual
only:
- master
然后管道将触发,并且当此存储库合并到主库时,将创建资源(S3和IAM用户),并且用户将具有该IAM用户的凭据。
现在的问题是,我们有多个AWS账户。可以这么说,如果开发人员想在某个帐户中创建S3,则上述设置将无法实现,因为 admin-user (其信誉属于gitlab机密)仅适用于一个帐户单独。
现在我不明白如何达到我的上述要求。我有以下想法:(请提出是否有更好的方法来做到这一点)
main.tf
module "aws-s3-john-doe" {
source = "git::https://git@gitlab-address/terraform/aws-s3-iam-combo.git?ref=v0.0.1"
name = "john-doe"
tag_team = "my_team"
tag_environment = "staging"
aws_account = "account1"
}
main.tf
中以某种方式从gitlab机密中读取 account1 的信条。现在我不知道如何实现上述目标,就像我如何从gitlab读取所需的秘密变量等。
有人可以在这里帮忙吗?
答案 0 :(得分:1)
您之前问过这个问题,但是也许我的想法仍然可以帮助一个或另一个...
您可以使用envsubst
进行此操作(要求将pkg gettext
安装在运行程序或用于运行管道的Docker映像中)。
这里是一个例子:
首先,在项目设置中,将不同的用户帐户设置为环境变量(项目机密:
SECRET_1: my-secret-1
SECRET_2: my-secret-2
SECRET_3: my-secret-3
然后,创建一个包含Terraform变量的文件,我们将其命名为vars_template.tf
:
variable "gitlab_secrets" {
description = "Variables from GitLab"
type = "map"
default = {
secret_1 = "$SECRET_1"
secret_2 = "$SECRET_2"
secret_3 = "$SECRET_3"
}
}
现在,您可以在CI管道中配置以下内容:
plan:dev:
stage: plan dev
script:
- envsubst < vars_template.tf > ./vars_envsubst.tf
- rm vars_template.tf
- terraform init
- terraform plan -out "planfile_dev"
artifacts:
paths:
- environments/dev/planfile_dev
- environments/dev/vars_envsubst.tf
apply:dev:
stage: apply dev
script:
- cd environments/dev
- rm vars_template.tf
- terraform init
- terraform apply -input=false "planfile_dev"
dependencies:
- plan:dev
请注意,必须删除原始的vars_template.tf
,否则Terraform将抛出错误,该变量被多次定义。您可以通过将模板文件存储在Terraform工作目录之外的目录中来规避此问题。
但是从Terraform状态中,您可以看到正确替换了变量值:
"outputs": {
"gitlab_secrets": {
"sensitive": false,
"type": "map",
"value": {
"secret_1": "my-secret-1",
"secret_2": "my-secret-2",
"secret_3": "my-secret-3"
}
}
}
然后您可以在Terraform资源等中使用"${vars.gitlab_secrets["secret_1"]}"
访问值。
更新:请注意,此方法会将机密信息存储在Terraform状态文件中,如果该文件存储在S3存储桶中以与Terraform协同工作,则可能是安全隐患。存储桶至少应加密。另外,建议使用ACL限制对文件的访问,例如,只有用户 terraform 可以访问它。而且,当然,用户可以通过Terraoform outputs
...