Reputation: 1876
I'm using a custom CloudFormation resource to generate an EC2 keypair for an automated install. I'm trying to remove as many manual steps as possible for a highly-automated server setup. Here is the portion of the CloudFormation template with the relevant code:
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
LambdaPolicy:
Type: AWS::IAM::Policy
DependsOn:
- LambdaRole
Properties:
PolicyName: CFNCustomSecretProviderPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:CreateAccessKey
- iam:DeleteAccessKey
- iam:UpdateAccessKey
- ssm:PutParameter
- ssm:GetParameter
- ssm:DeleteParameter
- ec2:ImportKeyPair
- ec2:DeleteKeyPair
Resource:
- '*'
- Effect: Allow
Action:
- kms:Encrypt
Resource:
- '*'
- Action:
- logs:*
Resource: arn:aws:logs:*:*:*
Effect: Allow
Roles:
- !Ref 'LambdaRole'
CFNSecretProvider:
Type: AWS::Lambda::Function
DependsOn:
- LambdaPolicy
Properties:
Description: CloudFormation Custom:Secret implementation
Code:
S3Bucket: !Sub 'binxio-public-${AWS::Region}'
S3Key: lambdas/cfn-secret-provider-0.11.0.zip
Handler: secrets.handler
MemorySize: 128
Timeout: 30
Role: !GetAtt 'LambdaRole.Arn'
Runtime: python2.7
PrivateKey:
Type: Custom::RSAKey
DependsOn: CFNSecretProvider
Properties:
Name: /mainframe/onyx-private-key
KeyAlias: alias/aws/ssm
ServiceToken: !Join
- ":"
- - arn:aws:lambda
- !Ref "AWS::Region"
- !Ref "AWS::AccountId"
- !Ref CFNSecretProvider
CustomKeyPair:
Type: Custom::KeyPair
DependsOn:
- CFNSecretProvider
- PrivateKey
Properties:
Name: CustomKeyPair
PublicKeyMaterial: !GetAtt
- PrivateKey
- PublicKey
ServiceToken: !Join
- ":"
- - arn:aws:lambda
- !Ref "AWS::Region"
- !Ref "AWS::AccountId"
- !Ref CFNSecretProvider
EC2Instance:
Type: AWS::EC2::Instance
DependsOn:
- CustomKeyPair
- InstanceProfile
Properties:
IamInstanceProfile: !Ref InstanceProfile
InstanceType: !Ref InstanceType
ImageId: !FindInMap [AWSRegionToAMI, !Ref "AWS::Region", AMI]
KeyName: !Ref CustomKeyPair
...
Everything in this seems to work great up until the instance is created. It fails claiming the keypair doesn't exist, even though the keypair is there after it runs, and I can query it:
∴ aws ec2 describe-key-pairs --region=us-east-2 --profile=mainframe-
personal
{
"KeyPairs": [
{
"KeyFingerprint": "90:42:11:40:a5:9b:66:af:78:ce:b4:d1:54:07:95:27",
"KeyName": "CustomKeyPair"
},
{
"KeyFingerprint": "27:5c:bf:4a:b2:f6:75:3b:8c:c3:1b:57:0d:7e:28:de:8e:cd:90:69",
"KeyName": "default"
}
]
}
The error I'm getting in the CloudFormation event log is The key pair 'arn:aws:ec2:us-east-2:685716241758:keypair/CustomKeyPair' does not exist. That ARN is exactly what is shown in the resource list. Is there some reason that CloudFormation can't find this keypair?
Upvotes: 1
Views: 4285
Reputation: 269320
The AWS::EC2::Instance - AWS CloudFormation documentation says:
KeyName: Provides the name of the Amazon EC2 key pair.
The error message is suggesting that an ARN was passed. Instead, try just passing the name (the last part of the ARN).
Upvotes: 3