In a test environment to mockup a larger issue, I have an IAM user with a directly attached IAM profile. I have also tried with the profile attached to an IAM Role which the IAM user has assumed.
The profile allows CloudFormation to create a VPC with IPv6CidrBlock and IPv6Cidr subnet. This cloud stack always is created fine in us-east-1 and some other regions. Upon further testing other regions always fail. The IPv6 subnet creation fails. Investigation found that one additional IAM profile action, "ec2:DescribeNetworkAcls" is needed for some regions. For example us-east-1 and eu-west-2 do not require the additional action. eu-central-1 and several other regions do require the additional IAM profile action.
- Is there any known reason for this different requirement among the regions? Is there any EC2 or VPC service setting which can be queried to see the difference?
- Why does CloudTrail not log the failure message when the IAM profile is missing the "ec2:DescribeNetworkAcls" action?
- For the previous failing regions, when the action is added to IAM profile, upon retest, CloudTrail does not log the successful event named "DescribeNetworkAcls" though it does log all other related events.
The error shown in CloudFormation, though not CloudTrail:
"ResourceStatus": "CREATE_FAILED",
LogicalId: Subnet,
"ResourceStatusReason":
"Unable to retrieve Ipv6CidrBlocks attribute for AWS::EC2::VPC, with error message You are not authorized to perform this operation. (Service: Ec2, Status Code: 403, Request ID: XXX, Extended Request ID: null)...
When the error occurs, adding the following IAM Policy action resolves the issue. Though still this eventName is never logged by CloudTrail:
"ec2:DescribeNetworkAcls"
Cloudformation Template:
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Test stack'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 172.16.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
VPCIPv6:
Type: AWS::EC2::VPCCidrBlock
Properties:
AmazonProvidedIpv6CidrBlock: true
VpcId: !Ref VPC
Subnet:
Type: AWS::EC2::Subnet
DependsOn:
- VPCIPv6
Properties:
CidrBlock: 172.16.254.0/23
Ipv6CidrBlock: !Select [0, !Cidr [!Select [0, !GetAtt 'VPC.Ipv6CidrBlocks'], 1, 64]]
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
IAM Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudFormationStackActions",
"Effect": "Allow",
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DescribeStacks",
"cloudformation:DescribeStackEvents",
"cloudformation:ListStackResources"
],
"Resource": [
"*"
]
},
{
{
"Sid": "TESTINGVPCIPv6Subnet",
"Effect": "Allow",
"Action": [
"ec2:CreateVpc",
"ec2:CreateSubnet",
"ec2:AssociateVpcCidrBlock",
"ec2:AssociateSubnetCidrBlock",
"ec2:ModifyVpcAttribute",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets"
],
"Resource": [
"*"
]
}
]
}
To reproduce:
- Save the above cloud formation text to a file named "a-test-stack-template.yaml"
- Set the temporary bash variable named
aws_cred_profile
with the aws credentials profile name to be used for the aws cli commands. The creds should be of the IAM user with the above IAM profile attached. Use default if there is only one set of credentials
aws_cred_profile=default
- AWS CLI Commands to test mockup:
aws_region=eu-central-1
# aws cli create-stack
test_env=$(aws cloudformation create-stack --region $aws_region --no-cli-pager \
--profile $aws_cred_profile --disable-rollback \
--stack-name test-$(date +%Y%b%d-%H%M%S) \
--template-body file://a-test-stack-template.yaml \
| sed -r -e 's/.*:stack\/(.*)\/.*/\1/' | sed '1d' | sed '2d')
echo $test_env
# repeat calls to list-stack-resources until the stack creation is complete
aws cloudformation list-stack-resources --region $aws_region --no-cli-pager \
--stack-name=$test_env --max-items=3