I am trying to assign a custom IAM role to a user (google account) in a GCP Project via Deployment Manager but received a 403 Error code.
I have followed the sample provided in the Google Cloud Platform repo:
https://github.com/GoogleCloudPlatform/deploymentmanager-samples/tree/master/community/cloud-foundation/templates/iam_member
Basically I created a configuration YAML file with the following content:
- path: ../iam_member.py
name: iam_member.py
resources:
- name: iam-member-oval-unity-test-0
type: iam_member.py
properties:
projectId: oval-unity-88908
type: string
roles:
- role: roles/GARawDataViewer
members:
- user:<USER_EMAIL>
GARawDataViewer is a custom role created in the project oval-unity-88908 and is the value of the user email address to whom I am trying to assign the custom IAM role.
Finally, I deployed running the following command:
gcloud deployment-manager deployments create deployment-oval-unity-member-test --config examples/oval_unity_member.yaml
After running the gcloud deployment-manager I received the following error message:
- code: CONDITION_NOT_MET
location: /deployments/deployment-oval-unity-member-test/resources/get-iam-policy-iam-member-oval-unity-test-0-0-0->$.properties->$.policy
message: |-
InputMapping for field [policy] for method [setIamPolicy] could not be set from input, mapping was: [$.gcpIamMemberBinding($.intent, $.inputs.policy.response, $.resource.properties)], and evaluation context was:
{
"deployment" : {
"id" : 4858392305054927640,
"name" : "deployment-oval-unity-member-test"
},
"extensions" : {
"EnableAdditionalJsonPathFunctions" : true,
"EnableGoogleTypeProviderFunctionsExperiment" : true
},
"inputs" : {
"policy" : {
"error" : {
"code" : "403",
"message" : "{\"code\":403,\"message\":\"The caller does not have permission\",\"status\":\"PERMISSION_DENIED\",\"statusMessage\":\"Forbidden\",\"requestPath\":\"https://cloudresourcemanager.googleapis.com/v1/projects/oval-unity-88908:getIamPolicy\",\"httpMethod\":\"POST\"}"
}
}
},
"intent" : "CREATE",
"matches" : [ ],
"project" : "dm-creation-project-0",
"requestId" : "f3c7f0c4-1ff7-3e26-a060-b0adc068866d",
"resource" : {
"name" : "get-iam-policy-iam-member-oval-unity-test-0-0-0",
"previous" : { },
"properties" : {
"member" : "<USER_EMAIL_ADDRESS!>",
"resource" : "oval-unity-88908",
"role" : "roles/GARawDataViewer"
},
"self" : { }
}
}
Error was:
Parameter for gcpIamMemberBinding at position 1 is not of type map, value was [null]
The interesting thing is that I have been able to deploy successfully assigning a predefined role like 'editor': roles/editor, but it is failing using a custom role.
I have even tried using the full path to the custom role: projects/oval-unity-88908/roles/GARawDataViewer
but still showing the same error.
Do you have any idea how could I solve this issue?
Thanks in advance!
The issue might be, that you did not gave the service account which is used by the deployment manager the proper rights to handle IAM things. As described here you can possibly fix this issue by completing the following steps:
Go to the IAM page in the GCP Console of your project.
If prompted, select your project from the list.
Look for the Google APIs service account, which has the email address in the following format: [PROJECT_NUMBER]#cloudservices.gserviceaccount.com.
Grant the APIs service account the roles/owner roles
Let me know if you need further help!
Related
My goal is to enable logging for a regional WebAcl via AWS CDK. This seems to be possible over Cloud Formation and there are the appropriate constructs in CDK. But when using the following code to create a Log Group and linking it in a LoggingConfiguration ...
const webAclLogGroup = new LogGroup(scope, "awsWafLogs", {
logGroupName: `aws-waf-logs`
});
// Create logging configuration with log group as destination
new CfnLoggingConfiguration(scope, "webAclLoggingConfiguration", {
logDestinationConfigs: webAclLogGroup.logGroupArn, // Arn of LogGroup
resourceArn: aclArn // Arn of Acl
});
... I get an exception during cdk deploy, stating that the string in the LogdestinationConfig is not a correct Arn (some parts of the Arn in the log messages have been removed):
Resource handler returned message: "Error reason: The ARN isn't valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: LOG_DESTINATION, parameter: arn:aws:logs:xxx:xxx:xxx-awswaflogsF99ED1BA-PAeH9Lt2Y3fi:* (Service: Wafv2, Status Code: 400, Request ID: xxx, Extended Request ID: null)"
I cannot see an error in the generated Cloud Formation code after cdk synth:
"webAclLoggingConfiguration": {
"id": "webAclLoggingConfiguration",
"path": "xxx/xxx/webAclLoggingConfiguration",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::WAFv2::LoggingConfiguration",
"aws:cdk:cloudformation:props": {
"logDestinationConfigs": [
{
"Fn::GetAtt": [
{
"Ref": "awsWafLogs58D3FD01"
},
"Arn"
]
}
],
"resourceArn": {
"Fn::GetAtt": [
"webACL",
"Arn"
]
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_wafv2.CfnLoggingConfiguration",
"version": "2.37.1"
}
},
I'm using Cdk with Typescript and the Cdk version is currently set to 2.37.1 but it also did not work with 2.16.0.
WAF has particular requirements to the naming and format of Logging Destination configs as described and shown in their docs.
Specifically, the ARN of the Log Group cannot end in :* which unfortunately is the return value for a Log Group ARN in Cloudformation.
A workaround would be to construct the required ARN format manually like this, which will omit the :* suffix. Also note that logDestinationConfigs takes a List of Strings, though only with exactly 1 element in it.
const webAclLogGroup = new LogGroup(scope, "awsWafLogs", {
logGroupName: `aws-waf-logs`
});
// Create logging configuration with log group as destination
new CfnLoggingConfiguration(scope, "webAclLoggingConfiguration", {
logDestinationConfigs: [
// Construct the different ARN format from the logGroupName
Stack.of(this).formatArn({
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
service: "logs",
resource: "log-group",
resourceName: webAclLogGroup.logGroupName,
})
],
resourceArn: aclArn // Arn of Acl
});
PS: I work for AWS on the CDK team.
The following is the error message I get:
Error listing project repositories. Error message: Error listing resources in a stack. Error message: Stack with id SC-xxxxxxxxxxxx-pp-xxxxxxxxxxxxx does not exist.
I checked, and a stack was created with the code commit repository but with a different id. I'm wondering where this stack with different id is coming from. Is this a permissions issue?
Edit: This is a custom sagemaker project created from this cloud formation template(which is a service catalog product).
---
Parameters:
SageMakerProjectId:
Description: "Service-generated id of the project"
NoEcho: true
Type: String
SageMakerProjectName:
AllowedPattern: "^[a-zA-Z](-*[a-zA-Z0-9])*"
Description: "Name of the project"
MaxLength: 32
MinLength: 1
NoEcho: true
Type: String
Resources:
ModelBuildCodeCommitRepository:
Properties:
Code:
BranchName: main
S3:
Bucket: sagemaker-servicecatalog-seedcode-us-west-2
Key: toolchain/image-build-model-building-workflow-v1.0.zip
RepositoryDescription:
? "Fn::Sub"
: "SageMaker Model building workflow infrastructure as code for the Project ${SageMakerProjectName}"
RepositoryName:
? "Fn::Sub"
: "${SageMakerProjectName}-${SageMakerProjectId}-modelbuild"
Type: "AWS::CodeCommit::Repository"
I'm trying to create a CloudFormation template that'll deploy a Lambda function, And I need the security options to be optional parameters.
I was able to partially accomplish this using the question here:
How to make a whole object in CloudFormation templates optional?
Interestingly, that method worked great to make the VpcConfig property optional in the AWS GUI Console, but it did NOT work to make it optional for the CLI. And unfortunately, I need it to work in the CLI, since I'll be using CodeBuild to call and deploy this template's resources.
Here are the relevant parameters:
"SecurityGroupIds" : {
"Type" : "CommaDelimitedList",
"Description" : "A list of one or more security groups IDs in the VPC that includes the resources to which your Lambda function requires access."
},
"SubnetIds" : {
"Type" : "CommaDelimitedList",
"Description" : "A list of one or more subnet IDs in the VPC that includes the resources to which your Lambda function requires access."
}
And conditions:
"HasVPC": {"Fn::And": [{"Fn::Not": [{"Fn::Equals": [{"Fn::Join": ["", {"Ref": "SubnetIds"}]}, ""]}]}, {"Fn::Not": [{"Fn::Equals": [{"Fn::Join": ["", {"Ref": "SecurityGroupIds"}]}, ""]}]}]}
And here's where that condition is used in the Lambda resource being defined in the Resources section of the template:
"VpcConfig": {
"Fn::If": [
"HasVPC",
{
"SecurityGroupIds" : {"Ref": "SecurityGroupIds"},
"SubnetIds" : {"Ref": "SubnetIds"}
},
{ "Ref":"AWS::NoValue" }
]
},
When I issue the command to deploy this stack in the CLI, I get the following error:
An error occurred (ValidationError) when calling the CreateChangeSet
operation: Parameters: [SecurityGroupIds, SubnetIds] must have values
Here's the AWS CLI command I'm issuing, from the same directory in which the template is located. Note: the ARN values have all been heavily modified to not be real values from my account, but I kept them in the right format so you can see the real format of the command:
aws cloudformation deploy --template-file lambda-template.json --stack-name "CLI-lambda-stack" --parameter-overrides S3BucketName="myBucket" S3FileLocation="lambda_function.zip" S3ObjectVersion="ZuB0iueEghOyh5q00.DiykLNudujdsc5" DeadLetterArn="arn:aws:sns:us-west-2:577898337216:CloudFormationTests" EnvironmentVariable="testing" KmsKeyArn="arn:aws:kms:us-west-2:504398934246:key/b24e7b72-a94d-6a3e-b848-165115c86212" HandlerFunctionName="lambda_function.lambda_handler" MemorySize="128" Role="arn:aws:iam::102893937243:role/serverless-test-default-us-east-1-lambdaRole" FuncName="myCLILambda"
You are not providing SecurityGroupIds neither SubnetIds default values and your are not providing them on your --parameter-overrides. Therefore, CloudFormation doesn't know how to process them if no values are provided.
Adding the Default statement should do the trick:
{
"Parameters" : {
"SecurityGroupIds" : {
"Type" : "CommaDelimitedList",
"Description" : "A list of one or more security groups IDs in the VPC that includes the resources to which your Lambda function requires access.",
"Default" : ""
},
"SubnetIds" : {
"Type" : "CommaDelimitedList",
"Description" : "A list of one or more subnet IDs in the VPC that includes the resources to which your Lambda function requires access.",
"Default" : ""
}
}
I have a user who can create roles iff there is an attached permission boundary. The user can execute this function via the AWS console and via API calls from the API. However, there does not seem to be a way to automate the process in CloudFormation. Is it possible to create a role in a CFT and attach a permissions boundary to it?
Permissions Boundary is now supported by the CloudFormation's schema https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html.
{
"Type" : "AWS::IAM::Role",
"Properties" : {
"AssumeRolePolicyDocument" : Json,
"ManagedPolicyArns" : [ String, ... ],
"MaxSessionDuration" : Integer,
"Path" : String,
"PermissionsBoundary" : String,
"Policies" : [ Policy, ... ],
"RoleName" : String
}
}
YAML
Type: AWS::IAM::Role
Properties :
AssumeRolePolicyDocument : Json
ManagedPolicyArns :
- String
MaxSessionDuration : Integer
Path : String
PermissionsBoundary : String
Policies :
- Policy
RoleName : String
As an aside, the support for it was available in Terraform before it was in CFT.
Any suggestions why this AWS CloudFormation keeps rolling back?
{
"Description" : "Single Instance",
"Resources" : {
"EC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"ImageId" : "ami-b73b63a0",
"InstanceType" : "t2.micro",
"KeyName" : "aws-key-here",
"Tags" : [
{
"Key" : "Name",
"Value" : "test"
}
],
"SubnetId" : {
"Fn::Select" : [ "0", { "Ref" : "Subnets" } ]
}
}
}
},
"Parameters": {
"Subnets": {
"Type": "List<AWS::EC2::Subnet::Id>",
"Description": "The list of SubnetIds, for at least two Availability Zones in the region in your Virtual Private Cloud (VPC)"
}
}
}
The specific error seems to be about the Subnets Ref:
Parameter validation failed: parameter value for parameter name Subnets does not exist. Rollback requested by user.
I have already created 1 valid Subnet in my AWS Management Console and tested that it works when spinning up an EC2 Instance manually.
Or is there a way of debugging this / getting more detailed output?
The Subnets Parameter in your template has a type List<AWS::EC2::Subnet::Id>, which requires a reference to a list of valid Subnet IDs. The error you are seeing means that you passed at least one invalid Subnet ID to the Subnet parameter.
If you're deploying your stack from the AWS CLI using aws cloudformation create-stack, you need to pass a valid parameter value using the --parameters ParameterKey=Subnets,ParameterValue=subnet-12345678 option.
If you're deploying from the Management Console, you need to specify stack parameters using the provided dialog, and select a Subnet ID from the drop-down list.
I faced the same problem. In my case I created the Key with name "mykey" in Mumbai Region. But when I actually started creating a Cloud Formation Infrastructure I changed the region to US-East. Now in my Cloud Formation Infrastructure I provided the name of Key as "mykey". Now the problem is the key "mykey" was created in Mumbai Region.
Hence I create the Key once again in "US-East" region and my problem vanished.
Regards
Hitesh
In my case it was a problem on credentials key and access key. My default values were another accounts one and I was trying to create a stack on a wrong account.