我已经设法设置了 Localstack 和 MySql 测试容器(在 groovy spock 中),如下所示:
@Shared
public static Network network = Network.newNetwork()
@Shared
@ClassRule
public static MySQLContainer mySql = new MySQLContainer(DockerImageName.parse('mysql:5.7'))
.withNetwork(network)
.withNetworkAliases(MY_SQL_HOST_NAME) as MySQLContainer
@Shared
@ClassRule
public static LocalStackContainer localStack = new LocalStackContainer(DockerImageName.parse('localstack/localstack:0.11.6'))
.withServices(SQS, LAMBDA, CLOUDWATCH, DYNAMODB, KMS, STS, IAM)
.withNetwork(network)
.withEnv('LAMBDA_DOCKER_NETWORK', network.name)
.withCopyFileToContainer(MountableFile.forHostPath(new File('the jar file').path), '/opt/code/localstack/lambda.jar')
.withCopyFileToContainer(MountableFile.forClasspathResource('seed.yaml'), '/init/seed.yaml')
- 这设置了一个桥接网络,以便两个容器可以
互相交流。还设置 LAMBDA_DOCKER_NETWORK 允许 lambda 与 MySql、SQS 等进行通信。
- 将 lambda jar 文件复制到容器中 (withCopyFileToContainer)
- 我还需要 KMS,因此 seed.yaml 会对其进行初始化(请参阅本地 KMS 文档)
一旦容器启动并运行,就可以使用 awslocal 和标准 CLI 命令部署 lambda:
def result = localStack.execInContainer(
'awslocal', 'lambda', 'create-function',
'--function-name', 'lambda-name',
'--runtime', 'java8',
'--handler', 'uk.co.blah.blah.Handler',
'--role', 'arn:aws:iam::123456:role/irrelevant',
'--zip-file', 'fileb://lambda.jar',
'--environment', "Variables={MY_SQL_USERNAME=${mySql.username},MY_SQL_PASSWORD=${encryptedDbPassword},PLATFORM_DB_URL=${"jdbc:mysql://${MY_SQL_HOST_NAME}:3306"}," +
"AWS_REGION=${localStack.region}}"
)
最后,可以在测试中手动触发 lambda,如下所示:
localStack.execInContainer('awslocal', 'lambda', 'invoke', '--function-name', 'lambda-name', 'output0.json')