Closed tomelliot16 closed 4 years ago
I understand the need of being able to test with specific resource attributes values but I don't think those values should be in the assert block. The assert block should only describe the expected result of applying the terraform config under certain circumstances (the input values and the mocked data source).
Do you have other example in mind where you'd like more control on the resource attributes ? That would help to design this feature
A real case I'm dealing with which came up with the thought is
resource "aws_kms_key" "key" {
description = "KMS key 1"
}
resource "aws_iam_role_policy" "policy" {
role = aws_iam_role.role.id
policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:GenerateDataKey*",
"kms:ReEncrypt*"
],
"Resource": [
"${aws_kms_key.key.id}"
]
}
EOF
}
resource "aws_iam_role" "role" {
name = "role"
assume_role_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
EOF
}
Where I want to assert each one of the above however when ids are not set they are only set as nil
aws_iam_role_policy.policy.role : <nil> != at-least-something-unique-for-role-arn
I also was thinking of asserting policies.
Also I tend to disagree that is doesn't belong in the assert block because it seems the natural place when comparing it with rspec or other mocking systems
expect(thing).to receive(:call_name).with(args).and_return(something)
basically we are expecting the provider to fill in some data that will be used for other things. I'm not sure I understand why you don't want to add the return to the assert block.
perhaps this would be fine
assert "aws_s3_bucket" "c" {
bucket = "my-tf-test-bucket"
}
mock_resource "aws_s3_bucket" "c" {
return {
id = "arn:aws:s3::0000000000:my-tf-test-bucket"
}
}
if its language you could change it to
expect "aws_s3_bucket" "c" {
bucket = "my-tf-test-bucket"
return {
id = "arn:aws:s3::0000000000:my-tf-test-bucket"
}
}
indeed, that's better with expect
rather than assert
. And it's easier to read (and write) with a single expect
block rather than splitting it betwen an assert
block and a mock
one :+1:
Hello @tomelliot16
I've started implemented support for mocking return values or resources in the mock-return
branch.
It's still work in progress but you can start testing it if you want
@nhurel I've gotten my team to work on this from Acquia https://github.com/acquia/terraspec/pull/1 I will open a PR to this repo
After playing around a bit somethings I have found that are missing. such as values returned from the provider once resource is created should probably be able to be mocked. Ex:
spec could be something like